home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1995 March / macformat-022.iso / Shareware City / Developers / src / out-of-phase-102-c / OutOfPhase 1.02 Source / OutOfPhase Folder / MainWindowStuff.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-11-23  |  83.0 KB  |  2,880 lines  |  [TEXT/KAHL]

  1. /* MainWindowStuff.c */
  2. /*****************************************************************************/
  3. /*                                                                           */
  4. /*    Out Of Phase:  Digital Music Synthesis on General Purpose Computers    */
  5. /*    Copyright (C) 1994  Thomas R. Lawrence                                 */
  6. /*                                                                           */
  7. /*    This program is free software; you can redistribute it and/or modify   */
  8. /*    it under the terms of the GNU General Public License as published by   */
  9. /*    the Free Software Foundation; either version 2 of the License, or      */
  10. /*    (at your option) any later version.                                    */
  11. /*                                                                           */
  12. /*    This program is distributed in the hope that it will be useful,        */
  13. /*    but WITHOUT ANY WARRANTY; without even the implied warranty of         */
  14. /*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          */
  15. /*    GNU General Public License for more details.                           */
  16. /*                                                                           */
  17. /*    You should have received a copy of the GNU General Public License      */
  18. /*    along with this program; if not, write to the Free Software            */
  19. /*    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.              */
  20. /*                                                                           */
  21. /*    Thomas R. Lawrence can be reached at tomlaw@world.std.com.             */
  22. /*                                                                           */
  23. /*****************************************************************************/
  24.  
  25. #include "MiscInfo.h"
  26. #include "Audit.h"
  27. #include "Debug.h"
  28. #include "Definitions.h"
  29.  
  30. #include "MainWindowStuff.h"
  31. #include "Memory.h"
  32. #include "Files.h"
  33. #include "WindowDispatcher.h"
  34. #include "Array.h"
  35. #include "CodeCenter.h"
  36. #include "TextEdit.h"
  37. #include "SampleList.h"
  38. #include "FunctionList.h"
  39. #include "AlgoSampList.h"
  40. #include "WaveTableList.h"
  41. #include "AlgoWaveTableList.h"
  42. #include "InstrList.h"
  43. #include "TrackList.h"
  44. #include "Alert.h"
  45. #include "StartupOpen.h"
  46. #include "CalculatorWindow.h"
  47. #include "GrowIcon.h"
  48. #include "Main.h"
  49. #include "DisassemblyWindow.h"
  50. #include "PcodeSystem.h"
  51. #include "DataMunging.h"
  52. #include "NumberDialog.h"
  53. #include "Numbers.h"
  54. #include "GlobalWindowMenuList.h"
  55. #include "BinaryCodedDecimal.h"
  56. #include "PlayPrefsDialog.h"
  57. #include "ImportWAVSample.h"
  58. #include "ImportRAWSample.h"
  59. #include "ImportAIFFSample.h"
  60. #include "BufferedFileInput.h"
  61. #include "BufferedFileOutput.h"
  62.  
  63.  
  64. #define MINTABCOUNT (1)
  65. #define MAXTABCOUNT (255)
  66. #define DEFAULTTABSIZE (2)
  67.  
  68.  
  69. #define MAINWINSIZEX (450)
  70. #define MAINWINSIZEY (250)
  71.  
  72. /* top-left corner */
  73. #define TRACKX(W,H) (-1)
  74. #define TRACKY(W,H) (-1)
  75. #define TRACKWIDTH(W,H) ((W) / 3)
  76. #define TRACKHEIGHT(W,H) ((H) / 3)
  77.  
  78. /* top-middle */
  79. #define WAVETABLEX(W,H) (TRACKX(W,H) + TRACKWIDTH(W,H) + 1)
  80. #define WAVETABLEY(W,H) (TRACKY(W,H))
  81. #define WAVETABLEWIDTH(W,H) (((W) - WAVETABLEX(W,H)) / 2)
  82. #define WAVETABLEHEIGHT(W,H) (TRACKHEIGHT(W,H))
  83.  
  84. /* top-right corner */
  85. #define SAMPLEX(W,H) (WAVETABLEX(W,H) + WAVETABLEWIDTH(W,H) + 1)
  86. #define SAMPLEY(W,H) (WAVETABLEY(W,H))
  87. #define SAMPLEWIDTH(W,H) ((W) - SAMPLEX(W,H) + 1)
  88. #define SAMPLEHEIGHT(W,H) (WAVETABLEHEIGHT(W,H))
  89.  
  90. /* middle-left */
  91. #define INSTRUMENTX(W,H) (TRACKX(W,H))
  92. #define INSTRUMENTY(W,H) (TRACKY(W,H) + TRACKHEIGHT(W,H))
  93. #define INSTRUMENTWIDTH(W,H) (TRACKWIDTH(W,H))
  94. #define INSTRUMENTHEIGHT(W,H) (((H) - INSTRUMENTY(W,H)) / 2)
  95.  
  96. /* middle-middle */
  97. #define ALGOWAVETABLEX(W,H) (WAVETABLEX(W,H))
  98. #define ALGOWAVETABLEY(W,H) (INSTRUMENTY(W,H))
  99. #define ALGOWAVETABLEWIDTH(W,H) (WAVETABLEWIDTH(W,H))
  100. #define ALGOWAVETABLEHEIGHT(W,H) (INSTRUMENTHEIGHT(W,H))
  101.  
  102. /* middle-right */
  103. #define ALGOSAMPLEX(W,H) (SAMPLEX(W,H))
  104. #define ALGOSAMPLEY(W,H) (ALGOWAVETABLEY(W,H))
  105. #define ALGOSAMPLEWIDTH(W,H) (SAMPLEWIDTH(W,H))
  106. #define ALGOSAMPLEHEIGHT(W,H) (ALGOWAVETABLEHEIGHT(W,H))
  107.  
  108. /* bottom-left corner */
  109. #define FUNCTIONX(W,H) (INSTRUMENTX(W,H))
  110. #define FUNCTIONY(W,H) (INSTRUMENTY(W,H) + INSTRUMENTHEIGHT(W,H))
  111. #define FUNCTIONWIDTH(W,H) (INSTRUMENTWIDTH(W,H))
  112. #define FUNCTIONHEIGHT(W,H) ((H) - FUNCTIONY(W,H) + 1)
  113.  
  114. /* bottom-middle and bottom-right corner */
  115. #define COMMENTX(W,H) (FUNCTIONX(W,H) + FUNCTIONWIDTH(W,H) + 1)
  116. #define COMMENTY(W,H) (FUNCTIONY(W,H) + 1)
  117. #define COMMENTWIDTH(W,H) ((W) - COMMENTX(W,H) + 1)
  118. #define COMMENTHEIGHT(W,H) (FUNCTIONHEIGHT(W,H) - 1)
  119.  
  120.  
  121. /* this structure contains all the information for a document */
  122. struct MainWindowRec
  123.     {
  124.         WinType*                        ScreenID;
  125.         MyBoolean                        EverBeenSaved;
  126.         FileSpec*                        TheFileLocation; /* only valid if EverBeenSaved is true */
  127.         FileType*                        TheFile; /* only valid if EverBeenSaved is true */
  128.         GenericWindowRec*        MyGenericWindow; /* how the window event dispatcher knows us */
  129.         MenuItemType*                MyMenuItem;
  130.  
  131.         FileSpec*                        DeleteUndoFileLocation; /* NIL = none */
  132.         FileType*                        DeleteUndoFile; /* NIL = none */
  133.  
  134.         ArrayRec*                        ListOfCalcWindows;
  135.         ArrayRec*                        ListOfDisassemblies;
  136.         CodeCenterRec*            CodeCenter; /* keeps all the object code */
  137.  
  138.         /* generic control parameters */
  139.         long                                TabSize;
  140.         TextEditRec*                CommentInfo;
  141.  
  142.         /* score data */
  143.         SampleListRec*            SampleList;
  144.         FunctionListRec*        FunctionList;
  145.         AlgoSampListRec*        AlgoSampList;
  146.         WaveTableListRec*        WaveTableList;
  147.         AlgoWaveTableListRec*    AlgoWaveTableList;
  148.         InstrListRec*                InstrumentList;
  149.         TrackListRec*                TrackList;
  150.  
  151.         MyBoolean                        StuffModified;
  152.  
  153.         /* playback preferences */
  154.         MyBoolean                        StereoPlayback;
  155.         MyBoolean                        SurroundEncoding;
  156.         long                                SamplingRate;
  157.         long                                EnvelopeUpdateRate;
  158.         LargeBCDType                DefaultBeatsPerMinute;
  159.         LargeBCDType                OverallVolumeScalingFactor;
  160.         OutputNumBitsType        OutputNumBits;
  161.         MyBoolean                        InterpolateOverTime;
  162.         MyBoolean                        InterpolateAcrossWaves;
  163.         LargeBCDType                ScanningGap;
  164.         LargeBCDType                BufferDuration;
  165.         MyBoolean                        ClipWarning;
  166.         char*                                SongPostProcessing;
  167.         MyBoolean                        SongPostProcessingEnable;
  168.     };
  169.  
  170.  
  171. static ArrayRec*                ListOfDocuments = NIL;
  172.  
  173.  
  174. /* initialize internal data structures for documents */
  175. MyBoolean                        InitializeDocuments(void)
  176.     {
  177.         APRINT(("+InitializeDocuments"));
  178.         ListOfDocuments = NewArray();
  179.         if (ListOfDocuments == NIL)
  180.             {
  181.                 APRINT(("-InitializeDocuments failed"));
  182.                 return False;
  183.             }
  184.         APRINT(("-InitializeDocuments"));
  185.         return True;
  186.     }
  187.  
  188.  
  189. /* clean up any internal data structures used for documents */
  190. void                                ShutdownDocuments(void)
  191.     {
  192.         APRINT(("+ShutdownDocuments"));
  193.         ERROR(ArrayGetLength(ListOfDocuments) != 0,PRERR(AllowResume,
  194.             "ShutdownDocuments:  Not all documents disposed of"));
  195.         DisposeArray(ListOfDocuments);
  196.         APRINT(("-ShutdownDocuments"));
  197.     }
  198.  
  199.  
  200. /* open a new document window and load the document in.  the function takes */
  201. /* ownership of the file specification. */
  202. void                                OpenDocument(FileSpec* TheFile)
  203.     {
  204.         MainWindowRec*        Window;
  205.  
  206.         /* allocation */
  207.         Window = (MainWindowRec*)AllocPtrCanFail(sizeof(MainWindowRec),"MainWindowRec");
  208.         if (Window == NIL)
  209.             {
  210.              FailurePoint1:
  211.                 AlertHalt("There is not enough memory available to open the document.",NIL);
  212.                 if (TheFile != NIL)
  213.                     {
  214.                         DisposeFileSpec(TheFile);
  215.                     }
  216.                 return;
  217.             }
  218.         if (!ArrayAppendElement(ListOfDocuments,Window))
  219.             {
  220.              FailurePoint2:
  221.                 ReleasePtr((char*)Window);
  222.                 goto FailurePoint1;
  223.             }
  224.  
  225.         /* constructing members */
  226.  
  227.         Window->TabSize = DEFAULTTABSIZE;
  228.  
  229.         Window->CodeCenter = NewCodeCenter();
  230.         if (Window->CodeCenter == NIL)
  231.             {
  232.              FailurePoint3:
  233.                 ArrayDeleteElement(ListOfDocuments,ArrayFindElement(ListOfDocuments,Window));
  234.                 goto FailurePoint2;
  235.             }
  236.  
  237.         Window->ScreenID = MakeNewWindow(eDocumentWindow,eWindowClosable,
  238.             eWindowZoomable,eWindowResizable,4 + WindowOtherEdgeWidths(eDocumentWindow),
  239.             4 + WindowTitleBarHeight(eDocumentWindow),MAINWINSIZEX,MAINWINSIZEY,
  240.             (void (*)(void*))&MainWindowUpdator,Window);
  241.         if (Window->ScreenID == 0)
  242.             {
  243.              FailurePoint4:
  244.                 DisposeCodeCenter(Window->CodeCenter);
  245.                 goto FailurePoint3;
  246.             }
  247.  
  248.         Window->CommentInfo = NewTextEdit(Window->ScreenID,
  249.             eTEHScrollBar | eTEVScrollBar,GetScreenFont(),9,
  250.             COMMENTX(MAINWINSIZEX,MAINWINSIZEY),COMMENTY(MAINWINSIZEX,MAINWINSIZEY),
  251.             COMMENTWIDTH(MAINWINSIZEX,MAINWINSIZEY),COMMENTHEIGHT(MAINWINSIZEX,MAINWINSIZEY));
  252.         if (Window->CommentInfo == NIL)
  253.             {
  254.              FailurePoint5:
  255.                 KillWindow(Window->ScreenID);
  256.                 goto FailurePoint4;
  257.             }
  258.  
  259.         Window->SampleList = NewSampleList(Window,Window->CodeCenter,
  260.             Window->ScreenID,SAMPLEX(MAINWINSIZEX,MAINWINSIZEY),
  261.             SAMPLEY(MAINWINSIZEX,MAINWINSIZEY),SAMPLEWIDTH(MAINWINSIZEX,MAINWINSIZEY),
  262.             SAMPLEHEIGHT(MAINWINSIZEX,MAINWINSIZEY));
  263.         if (Window->SampleList == NIL)
  264.             {
  265.              FailurePoint6:
  266.                 DisposeTextEdit(Window->CommentInfo);
  267.                 goto FailurePoint5;
  268.             }
  269.  
  270.         Window->FunctionList = NewFunctionList(Window,Window->CodeCenter,
  271.             Window->ScreenID,FUNCTIONX(MAINWINSIZEX,MAINWINSIZEY),
  272.             FUNCTIONY(MAINWINSIZEX,MAINWINSIZEY),FUNCTIONWIDTH(MAINWINSIZEX,MAINWINSIZEY),
  273.             FUNCTIONHEIGHT(MAINWINSIZEX,MAINWINSIZEY));
  274.         if (Window->FunctionList == NIL)
  275.             {
  276.              FailurePoint7:
  277.                 DisposeSampleList(Window->SampleList);
  278.                 goto FailurePoint6;
  279.             }
  280.  
  281.         Window->AlgoSampList = NewAlgoSampList(Window,Window->CodeCenter,
  282.             Window->ScreenID,ALGOSAMPLEX(MAINWINSIZEX,MAINWINSIZEY),
  283.             ALGOSAMPLEY(MAINWINSIZEX,MAINWINSIZEY),
  284.             ALGOSAMPLEWIDTH(MAINWINSIZEX,MAINWINSIZEY),
  285.             ALGOSAMPLEHEIGHT(MAINWINSIZEX,MAINWINSIZEY));
  286.         if (Window->AlgoSampList == NIL)
  287.             {
  288.              FailurePoint8:
  289.                 DisposeFunctionList(Window->FunctionList);
  290.                 goto FailurePoint7;
  291.             }
  292.  
  293.         Window->WaveTableList = NewWaveTableList(Window,Window->CodeCenter,
  294.             Window->ScreenID,WAVETABLEX(MAINWINSIZEX,MAINWINSIZEY),
  295.             WAVETABLEY(MAINWINSIZEX,MAINWINSIZEY),WAVETABLEWIDTH(MAINWINSIZEX,MAINWINSIZEY),
  296.             WAVETABLEHEIGHT(MAINWINSIZEX,MAINWINSIZEY));
  297.         if (Window->WaveTableList == NIL)
  298.             {
  299.              FailurePoint9:
  300.                 DisposeAlgoSampList(Window->AlgoSampList);
  301.                 goto FailurePoint8;
  302.             }
  303.  
  304.         Window->AlgoWaveTableList = NewAlgoWaveTableList(Window,Window->CodeCenter,
  305.             Window->ScreenID,ALGOWAVETABLEX(MAINWINSIZEX,MAINWINSIZEY),
  306.             ALGOWAVETABLEY(MAINWINSIZEX,MAINWINSIZEY),
  307.             ALGOWAVETABLEWIDTH(MAINWINSIZEX,MAINWINSIZEY),
  308.             ALGOWAVETABLEHEIGHT(MAINWINSIZEX,MAINWINSIZEY));
  309.         if (Window->AlgoWaveTableList == NIL)
  310.             {
  311.              FailurePoint10:
  312.                 DisposeWaveTableList(Window->WaveTableList);
  313.                 goto FailurePoint9;
  314.             }
  315.  
  316.         Window->InstrumentList = NewInstrList(Window,Window->CodeCenter,
  317.             Window->ScreenID,INSTRUMENTX(MAINWINSIZEX,MAINWINSIZEY),
  318.             INSTRUMENTY(MAINWINSIZEX,MAINWINSIZEY),INSTRUMENTWIDTH(MAINWINSIZEX,MAINWINSIZEY),
  319.             INSTRUMENTHEIGHT(MAINWINSIZEX,MAINWINSIZEY));
  320.         if (Window->InstrumentList == NIL)
  321.             {
  322.              FailurePoint11:
  323.                 DisposeAlgoWaveTableList(Window->AlgoWaveTableList);
  324.                 goto FailurePoint10;
  325.             }
  326.  
  327.         Window->TrackList = NewTrackList(Window,Window->CodeCenter,
  328.             Window->ScreenID,TRACKX(MAINWINSIZEX,MAINWINSIZEY),TRACKY(MAINWINSIZEX,MAINWINSIZEY),
  329.             TRACKWIDTH(MAINWINSIZEX,MAINWINSIZEY),TRACKHEIGHT(MAINWINSIZEX,MAINWINSIZEY));
  330.         if (Window->TrackList == NIL)
  331.             {
  332.              FailurePoint12:
  333.                 DisposeInstrList(Window->InstrumentList);
  334.                 goto FailurePoint11;
  335.             }
  336.  
  337.         Window->ListOfCalcWindows = NewArray();
  338.         if (Window->ListOfCalcWindows == NIL)
  339.             {
  340.              FailurePoint13:
  341.                 DisposeTrackList(Window->TrackList);
  342.                 goto FailurePoint12;
  343.             }
  344.  
  345.         Window->ListOfDisassemblies = NewArray();
  346.         if (Window->ListOfDisassemblies == NIL)
  347.             {
  348.              FailurePoint14:
  349.                 DisposeArray(Window->ListOfCalcWindows);
  350.                 goto FailurePoint13;
  351.             }
  352.  
  353.         Window->MyGenericWindow = CheckInNewWindow(Window->ScreenID,Window,
  354.             (void (*)(void*,MyBoolean,OrdType,OrdType,ModifierFlags))&MainWindowDoIdle,
  355.             (void (*)(void*))&MainWindowBecomeActive,
  356.             (void (*)(void*))&MainWindowBecomeInactive,
  357.             (void (*)(void*))&MainWindowJustResized,
  358.             (void (*)(OrdType,OrdType,ModifierFlags,void*))&MainWindowDoMouseDown,
  359.             (void (*)(unsigned char,ModifierFlags,void*))&MainWindowDoKeyDown,
  360.             (void (*)(void*))&MainWindowClose,
  361.             (void (*)(void*))&MainWindowMenuSetup,
  362.             (void (*)(void*,MenuItemType*))&MainWindowDoMenuCommand);
  363.         if (Window->MyGenericWindow == NIL)
  364.             {
  365.              FailurePoint15:
  366.                 DisposeArray(Window->ListOfDisassemblies);
  367.                 goto FailurePoint14;
  368.             }
  369.  
  370.         Window->MyMenuItem = MakeNewMenuItem(mmWindowMenu,"x",0);
  371.         if (Window->MyMenuItem == NIL)
  372.             {
  373.              FailurePoint16:
  374.                 CheckOutDyingWindow(Window->MyGenericWindow);
  375.                 goto FailurePoint15;
  376.             }
  377.         if (!RegisterWindowMenuItem(Window->MyMenuItem,(void (*)(void*))&ActivateThisWindow,
  378.             Window->ScreenID))
  379.             {
  380.              FailurePoint17:
  381.                 KillMenuItem(Window->MyMenuItem);
  382.                 goto FailurePoint16;
  383.             }
  384.  
  385.         Window->SongPostProcessing = StringToBlockCopy("#song postprocessing\x0a");
  386.         if (Window->SongPostProcessing == NIL)
  387.             {
  388.              FailurePoint18:
  389.                 DeregisterWindowMenuItem(Window->MyMenuItem);
  390.                 goto FailurePoint17;
  391.             }
  392.         SetTag(Window->SongPostProcessing,"SongPostProcessing");
  393.  
  394.         Window->StereoPlayback = True;
  395.         Window->SurroundEncoding = False;
  396.         Window->SamplingRate = 44100;
  397.         Window->EnvelopeUpdateRate = 441;
  398.         Window->DefaultBeatsPerMinute = Double2LargeBCD(120);
  399.         Window->OverallVolumeScalingFactor = Double2LargeBCD(1);
  400.         Window->OutputNumBits = eOutput16Bits;
  401.         Window->InterpolateOverTime = True;
  402.         Window->InterpolateAcrossWaves = True;
  403.         Window->StuffModified = False;
  404.         Window->ScanningGap = Double2LargeBCD(2);
  405.         Window->BufferDuration = Double2LargeBCD(8);
  406.         Window->ClipWarning = True;
  407.         Window->SongPostProcessingEnable = False;
  408.  
  409.         Window->DeleteUndoFileLocation = NIL;
  410.         Window->DeleteUndoFile = NIL;
  411.  
  412.         /* reading the data or making an empty instrument */
  413.         if (TheFile == NIL)
  414.             {
  415.                 /* create a new empty one */
  416.                 Window->EverBeenSaved = False;
  417.             }
  418.          else
  419.             {
  420.                 FileType*                    FileDesc;
  421.  
  422.                 /* read a file in and update the file refnum and location variables */
  423.                 if (OpenFile(TheFile,&FileDesc,eReadAndWrite))
  424.                     {
  425.                         BufferedInputRec*    InputFileThang;
  426.  
  427.                         InputFileThang = NewBufferedInput(FileDesc);
  428.                         if (InputFileThang == NIL)
  429.                             {
  430.                                 AlertHalt("There is not enough memory available to read the file.",NIL);
  431.                                 ReleasePtr(Window->SongPostProcessing);
  432.                                 goto FailurePoint18;
  433.                             }
  434.                          else
  435.                             {
  436.                                 FileLoadingErrors    Error;
  437.  
  438.                                 SetWatchCursor();
  439.                                 Error = MainWindowReadData(Window,InputFileThang);
  440.                                 if (Error == eFileLoadNoError)
  441.                                     {
  442.                                         Error = SampleListReadData(Window->SampleList,InputFileThang);
  443.                                         if (Error == eFileLoadNoError)
  444.                                             {
  445.                                                 Error = FunctionListReadData(Window->FunctionList,
  446.                                                     InputFileThang);
  447.                                                 if (Error == eFileLoadNoError)
  448.                                                     {
  449.                                                         Error = AlgoSampListReadData(Window->AlgoSampList,
  450.                                                             InputFileThang);
  451.                                                         if (Error == eFileLoadNoError)
  452.                                                             {
  453.                                                                 Error = WaveTableListReadData(Window->WaveTableList,
  454.                                                                     InputFileThang);
  455.                                                                 if (Error == eFileLoadNoError)
  456.                                                                     {
  457.                                                                         Error = AlgoWaveTableListReadData(
  458.                                                                             Window->AlgoWaveTableList,InputFileThang);
  459.                                                                         if (Error == eFileLoadNoError)
  460.                                                                             {
  461.                                                                                 Error = InstrListReadData(Window->InstrumentList,
  462.                                                                                     InputFileThang);
  463.                                                                                 if (Error == eFileLoadNoError)
  464.                                                                                     {
  465.                                                                                         Error = TrackListReadData(Window->TrackList,
  466.                                                                                             InputFileThang);
  467.                                                                                     }
  468.                                                                             }
  469.                                                                     }
  470.                                                             }
  471.                                                     }
  472.                                             }
  473.                                     }
  474.                                 switch (Error)
  475.                                     {
  476.                                         default:
  477.                                             EXECUTE(PRERR(ForceAbort,"OpenDocument:  bad error code"));
  478.                                             break;
  479.                                         case eFileLoadNoError:
  480.                                             break;
  481.                                         case eFileLoadBadFormat:
  482.                                             AlertHalt("The file format is unrecognized.",NIL);
  483.                                             break;
  484.                                         case eFileLoadDiskError:
  485.                                             AlertHalt("A disk error occurred and the file could not be "
  486.                                                 "completely loaded.",NIL);
  487.                                             break;
  488.                                         case eFileLoadOutOfMemory:
  489.                                             AlertHalt("There is not enough memory available to completely "
  490.                                                 "load the file.  Try closing windows or quitting other "
  491.                                                 "applications to make more memory available.",NIL);
  492.                                             break;
  493.                                     }
  494.                             }
  495.                         EndBufferedInput(InputFileThang);
  496.                         MainWindowDeselectAllOtherStringLists(Window,NIL/*deselect all*/);
  497.                     }
  498.                  else
  499.                     {
  500.                         AlertHalt("Unable to open file for reading.",NIL);
  501.                         ReleasePtr(Window->SongPostProcessing);
  502.                         goto FailurePoint18;
  503.                     }
  504.                 Window->EverBeenSaved = True;
  505.                 Window->TheFileLocation = TheFile;
  506.                 Window->TheFile = FileDesc;
  507.             }
  508.  
  509.         MainWindowDispatchNameChange(Window);
  510.     }
  511.  
  512.  
  513. /* save the document into the current file.  if it hasn't been saved, then call SaveAs */
  514. /* it returns False if it fails. */
  515. MyBoolean                        SaveDocument(MainWindowRec* Window)
  516.     {
  517.         CheckPtrExistence(Window);
  518.         if (!Window->EverBeenSaved)
  519.             {
  520.                 return SaveDocumentAs(Window);
  521.             }
  522.          else
  523.             {
  524.                 FileType*                    TempFile;
  525.                 FileSpec*                    TempFileLocation;
  526.                 BufferedOutputRec*    OutputFileThang;
  527.                 FileLoadingErrors    Error;
  528.  
  529.                 /* create new file and write the data out here */
  530.                 /* create a temporary file in the same directory */
  531.                 TempFileLocation = NewTempFileInTheSameDirectory(Window->TheFileLocation);
  532.                 if (TempFileLocation == NIL)
  533.                     {
  534.                      FailurePoint1:
  535.                         AlertHalt("Unable to write out the data.",NIL);
  536.                         return False;
  537.                     }
  538.                 /* open the file */
  539.                 if (!OpenFile(TempFileLocation,&TempFile,eReadAndWrite))
  540.                     {
  541.                      FailurePoint2:
  542.                         DisposeFileSpec(TempFileLocation);
  543.                         goto FailurePoint1;
  544.                     }
  545.                 /* write all the data out */
  546.                 OutputFileThang = NewBufferedOutput(TempFile);
  547.                 if (OutputFileThang == NIL)
  548.                     {
  549.                      FailurePoint3:
  550.                         CloseFile(TempFile);
  551.                         DeleteFile(TempFileLocation);
  552.                         goto FailurePoint2;
  553.                     }
  554.                 SetWatchCursor();
  555.                 Error = MainWindowWriteData(Window,OutputFileThang);
  556.                 if (Error == eFileLoadNoError)
  557.                     {
  558.                         Error = SampleListWriteData(Window->SampleList,OutputFileThang);
  559.                         if (Error == eFileLoadNoError)
  560.                             {
  561.                                 Error = FunctionListWriteData(Window->FunctionList,OutputFileThang);
  562.                                 if (Error == eFileLoadNoError)
  563.                                     {
  564.                                         Error = AlgoSampListWriteData(Window->AlgoSampList,OutputFileThang);
  565.                                         if (Error == eFileLoadNoError)
  566.                                             {
  567.                                                 Error = WaveTableListWriteData(Window->WaveTableList,
  568.                                                     OutputFileThang);
  569.                                                 if (Error == eFileLoadNoError)
  570.                                                     {
  571.                                                         Error = AlgoWaveTableListWriteData(Window->AlgoWaveTableList,
  572.                                                             OutputFileThang);
  573.                                                         if (Error == eFileLoadNoError)
  574.                                                             {
  575.                                                                 Error = InstrListWriteData(Window->InstrumentList,
  576.                                                                     OutputFileThang);
  577.                                                                 if (Error == eFileLoadNoError)
  578.                                                                     {
  579.                                                                         Error = TrackListWriteData(Window->TrackList,
  580.                                                                             OutputFileThang);
  581.                                                                         if (Error == eFileLoadNoError)
  582.                                                                             {
  583.                                                                                 if (EndBufferedOutput(OutputFileThang))
  584.                                                                                     {
  585.                                                                                         Error = eFileLoadNoError;
  586.                                                                                     }
  587.                                                                                  else
  588.                                                                                     {
  589.                                                                                         Error = eFileLoadDiskError;
  590.                                                                                     }
  591.                                                                             }
  592.                                                                     }
  593.                                                             }
  594.                                                     }
  595.                                             }
  596.                                     }
  597.                             }
  598.                     }
  599.                 switch (Error)
  600.                     {
  601.                         default:
  602.                             EXECUTE(PRERR(ForceAbort,"OpenDocument:  bad error code"));
  603.                             break;
  604.                         case eFileLoadNoError:
  605.                             break;
  606.                         case eFileLoadDiskError:
  607.                             AlertHalt("A disk error occurred and the file could not be saved.",NIL);
  608.                             goto FailurePoint3;
  609.                         case eFileLoadOutOfMemory:
  610.                             AlertHalt("There is not enough memory available to save the file.  "
  611.                                 "Try closing windows or quitting other applications to make more "
  612.                                 "memory available.",NIL);
  613.                             goto FailurePoint3;
  614.                     }
  615.                 FlushLocalBuffers(TempFile);
  616.                 /* swap the files on the disk */
  617.                 if (!SwapFileDataForks(TempFileLocation,Window->TheFileLocation,TempFile,
  618.                     &(Window->TheFile)))
  619.                     {
  620.                         /* if this fails, then the parameters are unaltered */
  621.                         goto FailurePoint3;
  622.                     }
  623.                 /* at this point, Window->TheFile has been fixed up, TempFile is closed, */
  624.                 /* and we need to dispose TempFileLocation */
  625.                 DisposeFileSpec(TempFileLocation);
  626.                 /* mark the data to indicate that it has been saved. */
  627.                 FunctionListMarkAllObjectsSaved(Window->FunctionList);
  628.                 SampleListMarkAllObjectsSaved(Window->SampleList);
  629.                 AlgoSampListMarkAllObjectsSaved(Window->AlgoSampList);
  630.                 WaveTableListMarkAllObjectsSaved(Window->WaveTableList);
  631.                 AlgoWaveTableListMarkAllObjectsSaved(Window->AlgoWaveTableList);
  632.                 InstrListMarkAllObjectsSaved(Window->InstrumentList);
  633.                 TrackListMarkAllObjectsSaved(Window->TrackList);
  634.                 TextEditHasBeenSaved(Window->CommentInfo);
  635.                 Window->StuffModified = False;
  636.                 /* return true since it saved correctly */
  637.                 return True;
  638.             }
  639.         EXECUTE(PRERR(ForceAbort,"SaveDocument:  control reached end of function"));
  640.     }
  641.  
  642.  
  643. /* close all open documents, subject to the user's ok */
  644. void                                DoCloseAllQuitPending(void)
  645.     {
  646.         while (ArrayGetLength(ListOfDocuments) > 0)
  647.             {
  648.                 MainWindowRec*        Window;
  649.  
  650.                 Window = (MainWindowRec*)ArrayGetElement(ListOfDocuments,0);
  651.                 ActivateThisWindow(Window->ScreenID);
  652.                 if (!CloseDocument(Window))
  653.                     {
  654.                         /* user cancelled */
  655.                         AbortQuitInProgress();
  656.                         return;
  657.                     }
  658.                 /* else keep going */
  659.             }
  660.     }
  661.  
  662.  
  663. /* close a document.  If the user cancelled, then return False, otherwise True */
  664. MyBoolean                        CloseDocument(MainWindowRec* Window)
  665.     {
  666.         long                Scan;
  667.  
  668.         CheckPtrExistence(Window);
  669.         if (HasDocumentBeenModified(Window))
  670.             {
  671.                 /* hafta ask permission */
  672.                 YesNoCancelType        WhatToDo;
  673.                 char*                            Filename;
  674.                 char*                            XFilename;
  675.  
  676.                 XFilename = GetCopyOfDocumentName(Window);
  677.                 if (XFilename == NIL)
  678.                     {
  679.                      FailurePoint1:
  680.                         AlertHalt("There is not enough memory to close the document.",NIL);
  681.                         return False;
  682.                     }
  683.                 Filename = BlockToStringCopy(XFilename);
  684.                 ReleasePtr(XFilename);
  685.                 if (Filename == NIL)
  686.                     {
  687.                         goto FailurePoint1;
  688.                     }
  689.                 WhatToDo = AskYesNoCancel("Save changes to document '_'?",
  690.                     Filename,"Save","Don't Save","Cancel");
  691.                 ReleasePtr(Filename);
  692.                 if (WhatToDo == eYes)
  693.                     {
  694.                         if (!SaveDocument(Window))
  695.                             {
  696.                                 /* save was cancelled or failed */
  697.                                 return False;
  698.                             }
  699.                     }
  700.                 else if (WhatToDo == eCancel)
  701.                     {
  702.                         return False; /* user cancelled */
  703.                     }
  704.                 /* fall through to deletion point */
  705.             }
  706.  
  707.         if (Window->DeleteUndoFileLocation != NIL)
  708.             {
  709.                 CloseFile(Window->DeleteUndoFile);
  710.                 DeleteFile(Window->DeleteUndoFileLocation);
  711.                 DisposeFileSpec(Window->DeleteUndoFileLocation);
  712.             }
  713.  
  714.         /* perform the data deletion here */
  715.         DisposeFunctionList(Window->FunctionList);
  716.         DisposeSampleList(Window->SampleList);
  717.         DisposeAlgoSampList(Window->AlgoSampList);
  718.         DisposeWaveTableList(Window->WaveTableList);
  719.         DisposeAlgoWaveTableList(Window->AlgoWaveTableList);
  720.         DisposeInstrList(Window->InstrumentList);
  721.         DisposeTrackList(Window->TrackList);
  722.  
  723.         DisposeTextEdit(Window->CommentInfo);
  724.  
  725.         for (Scan = 0; Scan < ArrayGetLength(Window->ListOfCalcWindows); Scan += 1)
  726.             {
  727.                 DisposeCalculatorWindow((CalcWindowRec*)ArrayGetElement(
  728.                     Window->ListOfCalcWindows,Scan));
  729.             }
  730.         DisposeArray(Window->ListOfCalcWindows);
  731.  
  732.         for (Scan = 0; Scan < ArrayGetLength(Window->ListOfDisassemblies); Scan += 1)
  733.             {
  734.                 DisposeDisassemblyWindow((DisaWindowRec*)ArrayGetElement(
  735.                     Window->ListOfDisassemblies,Scan));
  736.             }
  737.         DisposeArray(Window->ListOfDisassemblies);
  738.  
  739.         /* delete object code */
  740.         DisposeCodeCenter(Window->CodeCenter);
  741.  
  742.         ReleasePtr(Window->SongPostProcessing);
  743.  
  744.         DeregisterWindowMenuItem(Window->MyMenuItem);
  745.         KillMenuItem(Window->MyMenuItem);
  746.         CheckOutDyingWindow(Window->MyGenericWindow);
  747.         KillWindow(Window->ScreenID);
  748.         if (Window->EverBeenSaved)
  749.             {
  750.                 CloseFile(Window->TheFile);
  751.                 DisposeFileSpec(Window->TheFileLocation);
  752.             }
  753.         ERROR(ArrayFindElement(ListOfDocuments,Window) < 0,PRERR(ForceAbort,
  754.             "CloseDocument:  couldn't find document in the list"));
  755.         ArrayDeleteElement(ListOfDocuments,ArrayFindElement(ListOfDocuments,Window));
  756.         ReleasePtr((char*)Window);
  757.         return True;
  758.     }
  759.  
  760.  
  761. /* save the document into a new file (don't disturb the current one).  returns False */
  762. /* if it fails.  this function calls SaveDocument() to do the work. */
  763. MyBoolean                        SaveDocumentAs(MainWindowRec* Window)
  764.     {
  765.         FileSpec*                    NewWhere;
  766.         char*                            FilenameNull;
  767.         char*                            StringTempFileNameThing;
  768.  
  769.         CheckPtrExistence(Window);
  770.         StringTempFileNameThing = GetCopyOfDocumentName(Window);
  771.         if (StringTempFileNameThing == NIL)
  772.             {
  773.              FailurePoint1:
  774.                 AlertHalt("There is not enough memory to save the document.",NIL);
  775.                 return False;
  776.             }
  777.         FilenameNull = BlockToStringCopy(StringTempFileNameThing);
  778.         ReleasePtr(StringTempFileNameThing);
  779.         if (FilenameNull == NIL)
  780.             {
  781.                 goto FailurePoint1;
  782.             }
  783.         /* where do they want to save it */
  784.         NewWhere = PutFile(FilenameNull);
  785.         ReleasePtr(FilenameNull);
  786.         if (NewWhere != NIL)
  787.             {
  788.                 FileType*                    NewFile;
  789.                 char*                            XFilename;
  790.                 MyBoolean                    SaveWasSuccessful;
  791.  
  792.                 XFilename = ExtractFileName(NewWhere);
  793.                 if (XFilename == NIL)
  794.                     {
  795.                         goto FailurePoint1;
  796.                     }
  797.                 FilenameNull = BlockToStringCopy(XFilename);
  798.                 ReleasePtr(XFilename);
  799.                 if (FilenameNull == NIL)
  800.                     {
  801.                         goto FailurePoint1;
  802.                     }
  803.                 if (!CreateFile(NewWhere,ApplicationCreator,ApplicationFileType))
  804.                     {
  805.                         AlertHalt("Couldn't create the file '_'.",FilenameNull);
  806.                         ReleasePtr(FilenameNull);
  807.                         return False;
  808.                     }
  809.                 if (!OpenFile(NewWhere,&NewFile,eReadAndWrite))
  810.                     {
  811.                         AlertHalt("Couldn't open the file '_'.",FilenameNull);
  812.                         ReleasePtr(FilenameNull);
  813.                         return False;
  814.                     }
  815.                 if (Window->EverBeenSaved)
  816.                     {
  817.                         CloseFile(Window->TheFile);
  818.                         DisposeFileSpec(Window->TheFileLocation);
  819.                         Window->EverBeenSaved = False;
  820.                     }
  821.                 Window->EverBeenSaved = True;
  822.                 Window->TheFileLocation = NewWhere;
  823.                 Window->TheFile = NewFile;
  824.                 ReleasePtr(FilenameNull);
  825.                 SaveWasSuccessful = SaveDocument(Window);
  826.                 if (!SaveWasSuccessful)
  827.                     {
  828.                         /* if save wasn't successful, then get rid of the file stuff */
  829.                         CloseFile(Window->TheFile);
  830.                         DeleteFile(Window->TheFileLocation);
  831.                         DisposeFileSpec(Window->TheFileLocation);
  832.                         Window->EverBeenSaved = False;
  833.                     }
  834.                 MainWindowDispatchNameChange(Window);
  835.                 return SaveWasSuccessful;
  836.             }
  837.          else
  838.             {
  839.                 return False;
  840.             }
  841.         EXECUTE(PRERR(ForceAbort,"SaveDocumentAs:  control reached end of function"));
  842.     }
  843.  
  844.  
  845. /* return True if the document has been modified & should be saved. */
  846. MyBoolean                        HasDocumentBeenModified(MainWindowRec* Window)
  847.     {
  848.         CheckPtrExistence(Window);
  849.         return Window->StuffModified
  850.             || TextEditDoesItNeedToBeSaved(Window->CommentInfo)
  851.             || DoesFunctionListNeedToBeSaved(Window->FunctionList)
  852.             || DoesSampleListNeedToBeSaved(Window->SampleList)
  853.             || DoesAlgoSampListNeedToBeSaved(Window->AlgoSampList)
  854.             || DoesWaveTableListNeedToBeSaved(Window->WaveTableList)
  855.             || DoesAlgoWaveTableListNeedToBeSaved(Window->AlgoWaveTableList)
  856.             || DoesInstrListNeedToBeSaved(Window->InstrumentList)
  857.             || DoesTrackListNeedToBeSaved(Window->TrackList);
  858.     }
  859.  
  860.  
  861. void                                MainWindowDoIdle(MainWindowRec* Window,
  862.                                             MyBoolean CheckCursorFlag, OrdType XLoc, OrdType YLoc,
  863.                                             ModifierFlags Modifiers)
  864.     {
  865.         CheckPtrExistence(Window);
  866.         TextEditUpdateCursor(Window->CommentInfo);
  867.         if (CheckCursorFlag)
  868.             {
  869.                 if (TextEditIBeamTest(Window->CommentInfo,XLoc,YLoc))
  870.                     {
  871.                         SetIBeamCursor();
  872.                     }
  873.                  else
  874.                     {
  875.                         SetArrowCursor();
  876.                     }
  877.             }
  878.     }
  879.  
  880.  
  881. void                                MainWindowBecomeActive(MainWindowRec* Window)
  882.     {
  883.         OrdType            XSize;
  884.         OrdType            YSize;
  885.  
  886.         CheckPtrExistence(Window);
  887.         EnableTextEditSelection(Window->CommentInfo);
  888.         FunctionListBecomeActive(Window->FunctionList);
  889.         SampleListBecomeActive(Window->SampleList);
  890.         AlgoSampListBecomeActive(Window->AlgoSampList);
  891.         WaveTableListBecomeActive(Window->WaveTableList);
  892.         AlgoWaveTableListBecomeActive(Window->AlgoWaveTableList);
  893.         InstrListBecomeActive(Window->InstrumentList);
  894.         TrackListBecomeActive(Window->TrackList);
  895.         XSize = GetWindowWidth(Window->ScreenID);
  896.         YSize = GetWindowHeight(Window->ScreenID);
  897.         SetClipRect(Window->ScreenID,XSize - 15,YSize - 15,XSize,YSize);
  898.         DrawBitmap(Window->ScreenID,XSize-15,YSize-15,GetGrowIcon(True/*enablegrowicon*/));
  899.     }
  900.  
  901.  
  902. void                                MainWindowBecomeInactive(MainWindowRec* Window)
  903.     {
  904.         OrdType            XSize;
  905.         OrdType            YSize;
  906.  
  907.         CheckPtrExistence(Window);
  908.         DisableTextEditSelection(Window->CommentInfo);
  909.         FunctionListBecomeInactive(Window->FunctionList);
  910.         SampleListBecomeInactive(Window->SampleList);
  911.         AlgoSampListBecomeInactive(Window->AlgoSampList);
  912.         WaveTableListBecomeInactive(Window->WaveTableList);
  913.         AlgoWaveTableListBecomeInactive(Window->AlgoWaveTableList);
  914.         InstrListBecomeInactive(Window->InstrumentList);
  915.         TrackListBecomeInactive(Window->TrackList);
  916.         XSize = GetWindowWidth(Window->ScreenID);
  917.         YSize = GetWindowHeight(Window->ScreenID);
  918.         SetClipRect(Window->ScreenID,XSize - 15,YSize - 15,XSize,YSize);
  919.         DrawBitmap(Window->ScreenID,XSize-15,YSize-15,GetGrowIcon(False/*disablegrowicon*/));
  920.     }
  921.  
  922.  
  923. void                                MainWindowJustResized(MainWindowRec* Window)
  924.     {
  925.         OrdType            XSize;
  926.         OrdType            YSize;
  927.  
  928.         CheckPtrExistence(Window);
  929.         XSize = GetWindowWidth(Window->ScreenID);
  930.         YSize = GetWindowHeight(Window->ScreenID);
  931.         SetClipRect(Window->ScreenID,0,0,XSize,YSize);
  932.         DrawBoxErase(Window->ScreenID,0,0,XSize,YSize);
  933.         SetTextEditPosition(Window->CommentInfo,
  934.             COMMENTX(XSize,YSize),COMMENTY(XSize,YSize),
  935.             COMMENTWIDTH(XSize,YSize),COMMENTHEIGHT(XSize,YSize));
  936.         SetFunctionListLocation(Window->FunctionList,
  937.             FUNCTIONX(XSize,YSize),FUNCTIONY(XSize,YSize),
  938.             FUNCTIONWIDTH(XSize,YSize),FUNCTIONHEIGHT(XSize,YSize));
  939.         SetSampleListLocation(Window->SampleList,
  940.             SAMPLEX(XSize,YSize),SAMPLEY(XSize,YSize),
  941.             SAMPLEWIDTH(XSize,YSize),SAMPLEHEIGHT(XSize,YSize));
  942.         SetAlgoSampListLocation(Window->AlgoSampList,
  943.             ALGOSAMPLEX(XSize,YSize),ALGOSAMPLEY(XSize,YSize),
  944.             ALGOSAMPLEWIDTH(XSize,YSize),ALGOSAMPLEHEIGHT(XSize,YSize));
  945.         SetWaveTableListLocation(Window->WaveTableList,
  946.             WAVETABLEX(XSize,YSize),WAVETABLEY(XSize,YSize),WAVETABLEWIDTH(XSize,YSize),
  947.             WAVETABLEHEIGHT(XSize,YSize));
  948.         SetAlgoWaveTableListLocation(Window->AlgoWaveTableList,
  949.             ALGOWAVETABLEX(XSize,YSize),ALGOWAVETABLEY(XSize,YSize),
  950.             ALGOWAVETABLEWIDTH(XSize,YSize),ALGOWAVETABLEHEIGHT(XSize,YSize));
  951.         SetInstrListLocation(Window->InstrumentList,INSTRUMENTX(XSize,YSize),
  952.             INSTRUMENTY(XSize,YSize),INSTRUMENTWIDTH(XSize,YSize),INSTRUMENTHEIGHT(XSize,YSize));
  953.         SetTrackListLocation(Window->TrackList,TRACKX(XSize,YSize),TRACKY(XSize,YSize),
  954.             TRACKWIDTH(XSize,YSize),TRACKHEIGHT(XSize,YSize));
  955.     }
  956.  
  957.  
  958. void                                MainWindowDoMouseDown(OrdType XLoc, OrdType YLoc,
  959.                                             ModifierFlags Modifiers, MainWindowRec* Window)
  960.     {
  961.         CheckPtrExistence(Window);
  962.         if ((XLoc >= GetWindowWidth(Window->ScreenID) - 15)
  963.             && (XLoc < GetWindowWidth(Window->ScreenID))
  964.             && (YLoc >= GetWindowHeight(Window->ScreenID) - 15)
  965.             && (YLoc < GetWindowHeight(Window->ScreenID)))
  966.             {
  967.                 UserGrowWindow(Window->ScreenID,XLoc,YLoc);
  968.                 MainWindowJustResized(Window);
  969.             }
  970.         else if (TextEditHitTest(Window->CommentInfo,XLoc,YLoc))
  971.             {
  972.                 TextEditDoMouseDown(Window->CommentInfo,XLoc,YLoc,Modifiers);
  973.             }
  974.         else if (FunctionListHitTest(Window->FunctionList,XLoc,YLoc))
  975.             {
  976.                 MainWindowDeselectAllOtherStringLists(Window,Window->FunctionList);
  977.                 FunctionListDoMouseDown(Window->FunctionList,XLoc,YLoc,Modifiers);
  978.             }
  979.         else if (SampleListHitTest(Window->SampleList,XLoc,YLoc))
  980.             {
  981.                 MainWindowDeselectAllOtherStringLists(Window,Window->SampleList);
  982.                 SampleListDoMouseDown(Window->SampleList,XLoc,YLoc,Modifiers);
  983.             }
  984.         else if (AlgoSampListHitTest(Window->AlgoSampList,XLoc,YLoc))
  985.             {
  986.                 MainWindowDeselectAllOtherStringLists(Window,Window->AlgoSampList);
  987.                 AlgoSampListDoMouseDown(Window->AlgoSampList,XLoc,YLoc,Modifiers);
  988.             }
  989.         else if (WaveTableListHitTest(Window->WaveTableList,XLoc,YLoc))
  990.             {
  991.                 MainWindowDeselectAllOtherStringLists(Window,Window->WaveTableList);
  992.                 WaveTableListDoMouseDown(Window->WaveTableList,XLoc,YLoc,Modifiers);
  993.             }
  994.         else if (AlgoWaveTableListHitTest(Window->AlgoWaveTableList,XLoc,YLoc))
  995.             {
  996.                 MainWindowDeselectAllOtherStringLists(Window,Window->AlgoWaveTableList);
  997.                 AlgoWaveTableListDoMouseDown(Window->AlgoWaveTableList,XLoc,YLoc,Modifiers);
  998.             }
  999.         else if (InstrListHitTest(Window->InstrumentList,XLoc,YLoc))
  1000.             {
  1001.                 MainWindowDeselectAllOtherStringLists(Window,Window->InstrumentList);
  1002.                 InstrListDoMouseDown(Window->InstrumentList,XLoc,YLoc,Modifiers);
  1003.             }
  1004.         else if (TrackListHitTest(Window->TrackList,XLoc,YLoc))
  1005.             {
  1006.                 MainWindowDeselectAllOtherStringLists(Window,Window->TrackList);
  1007.                 TrackListDoMouseDown(Window->TrackList,XLoc,YLoc,Modifiers);
  1008.             }
  1009.     }
  1010.  
  1011.  
  1012. void                                MainWindowDoKeyDown(unsigned char KeyCode, ModifierFlags Modifiers,
  1013.                                             MainWindowRec* Window)
  1014.     {
  1015.         CheckPtrExistence(Window);
  1016.         TextEditDoKeyPressed(Window->CommentInfo,KeyCode,Modifiers);
  1017.     }
  1018.  
  1019.  
  1020. void                                MainWindowClose(MainWindowRec* Window)
  1021.     {
  1022.         CheckPtrExistence(Window);
  1023.         CloseDocument(Window);
  1024.     }
  1025.  
  1026.  
  1027. void                                MainWindowUpdator(MainWindowRec* Window)
  1028.     {
  1029.         OrdType                        XSize;
  1030.         OrdType                        YSize;
  1031.  
  1032.         CheckPtrExistence(Window);
  1033.         FunctionListRedraw(Window->FunctionList);
  1034.         SampleListRedraw(Window->SampleList);
  1035.         AlgoSampListRedraw(Window->AlgoSampList);
  1036.         WaveTableListRedraw(Window->WaveTableList);
  1037.         AlgoWaveTableListRedraw(Window->AlgoWaveTableList);
  1038.         InstrListRedraw(Window->InstrumentList);
  1039.         TrackListRedraw(Window->TrackList);
  1040.         TextEditFullRedraw(Window->CommentInfo);
  1041.         XSize = GetWindowWidth(Window->ScreenID);
  1042.         YSize = GetWindowHeight(Window->ScreenID);
  1043.         SetClipRect(Window->ScreenID,XSize - 15,YSize - 15,XSize,YSize);
  1044.         DrawBitmap(Window->ScreenID,XSize-15,YSize-15,
  1045.             GetGrowIcon(Window->MyGenericWindow == GetCurrentWindowID()));
  1046.     }
  1047.  
  1048.  
  1049. /* enable global menu items.  these are menu items that can be chosen regardless */
  1050. /* of which editor is open (such as New Object, Save...) */
  1051. void                                MainWindowMenuSetup(MainWindowRec* Window)
  1052.     {
  1053.         MainWindowEnableGlobalMenus(Window);
  1054.         EnableMenuItem(mPaste);
  1055.         if (TextEditIsThereValidSelection(Window->CommentInfo))
  1056.             {
  1057.                 EnableMenuItem(mCut);
  1058.                 EnableMenuItem(mCopy);
  1059.                 EnableMenuItem(mClear);
  1060.             }
  1061.         EnableMenuItem(mSelectAll);
  1062.         if (TextEditCanWeUndo(Window->CommentInfo))
  1063.             {
  1064.                 EnableMenuItem(mUndo);
  1065.                 ChangeItemName(mUndo,"Undo Text Edit");
  1066.             }
  1067.         if (Window->DeleteUndoFileLocation != NIL)
  1068.             {
  1069.                 EnableMenuItem(mUndo);
  1070.                 ChangeItemName(mUndo,"Undo Object Deletion");
  1071.             }
  1072.         ChangeItemName(mCloseFile,"Close Document");
  1073.         EnableMenuItem(mCloseFile);
  1074.  
  1075.         EnableMenuItem(mPasteObject);
  1076.         EnableMenuItem(mCopyObject);
  1077.         EnableMenuItem(mOpenObject);
  1078.         EnableMenuItem(mDeleteObject);
  1079.         if (FunctionListIsThereSelection(Window->FunctionList))
  1080.             {
  1081.                 ChangeItemName(mOpenObject,"Edit Function Module");
  1082.                 ChangeItemName(mDeleteObject,"Delete Function Module");
  1083.                 ChangeItemName(mCopyObject,"Copy Function Module");
  1084.             }
  1085.         else if (SampleListIsThereSelection(Window->SampleList))
  1086.             {
  1087.                 ChangeItemName(mOpenObject,"Edit Sample");
  1088.                 ChangeItemName(mDeleteObject,"Delete Sample");
  1089.                 ChangeItemName(mCopyObject,"Copy Sample");
  1090.             }
  1091.         else if (AlgoSampListIsThereSelection(Window->AlgoSampList))
  1092.             {
  1093.                 ChangeItemName(mOpenObject,"Edit Algorithmic Sample");
  1094.                 ChangeItemName(mDeleteObject,"Delete Algorithmic Sample");
  1095.                 ChangeItemName(mCopyObject,"Copy Algorithmic Sample");
  1096.             }
  1097.         else if (WaveTableListIsThereSelection(Window->WaveTableList))
  1098.             {
  1099.                 ChangeItemName(mOpenObject,"Edit Wave Table");
  1100.                 ChangeItemName(mDeleteObject,"Delete Wave Table");
  1101.                 ChangeItemName(mCopyObject,"Copy Wave Table");
  1102.             }
  1103.         else if (AlgoWaveTableListIsThereSelection(Window->AlgoWaveTableList))
  1104.             {
  1105.                 ChangeItemName(mOpenObject,"Edit Algorithmic Wave Table");
  1106.                 ChangeItemName(mDeleteObject,"Delete Algorithmic Wave Table");
  1107.                 ChangeItemName(mCopyObject,"Copy Algorithmic Wave Table");
  1108.             }
  1109.         else if (InstrListIsThereSelection(Window->InstrumentList))
  1110.             {
  1111.                 ChangeItemName(mOpenObject,"Edit Instrument");
  1112.                 ChangeItemName(mDeleteObject,"Delete Instrument");
  1113.                 ChangeItemName(mCopyObject,"Copy Instrument");
  1114.             }
  1115.         else if (TrackListIsThereSelection(Window->TrackList))
  1116.             {
  1117.                 ChangeItemName(mOpenObject,"Edit Track");
  1118.                 ChangeItemName(mDeleteObject,"Delete Track");
  1119.                 ChangeItemName(mCopyObject,"Copy Track");
  1120.             }
  1121.         else
  1122.             {
  1123.                 DisableMenuItem(mOpenObject);
  1124.                 DisableMenuItem(mDeleteObject);
  1125.                 DisableMenuItem(mCopyObject);
  1126.             }
  1127.         SetItemCheckmark(Window->MyMenuItem);
  1128.     }
  1129.  
  1130.  
  1131. void                                MainWindowDoMenuCommand(MainWindowRec* Window,
  1132.                                             MenuItemType* MenuItem)
  1133.     {
  1134.         CheckPtrExistence(Window);
  1135.         if (MainWindowDoGlobalMenuItem(Window,MenuItem))
  1136.             {
  1137.             }
  1138.         else if (MenuItem == mPaste)
  1139.             {
  1140.                 TextEditDoMenuPaste(Window->CommentInfo);
  1141.             }
  1142.         else if (MenuItem == mCut)
  1143.             {
  1144.                 TextEditDoMenuCut(Window->CommentInfo);
  1145.             }
  1146.         else if (MenuItem == mCopy)
  1147.             {
  1148.                 TextEditDoMenuCopy(Window->CommentInfo);
  1149.             }
  1150.         else if (MenuItem == mClear)
  1151.             {
  1152.                 TextEditDoMenuClear(Window->CommentInfo);
  1153.             }
  1154.         else if (MenuItem == mSelectAll)
  1155.             {
  1156.                 TextEditDoMenuSelectAll(Window->CommentInfo);
  1157.             }
  1158.         else if (MenuItem == mUndo)
  1159.             {
  1160.                 /* object deletion undo takes precedence */
  1161.                 if (Window->DeleteUndoFileLocation != NIL)
  1162.                     {
  1163.                         MyBoolean                    DidIt = True;
  1164.  
  1165.                         SetWatchCursor();
  1166.                         if (!FunctionListPasteFromFile(Window->FunctionList,
  1167.                             Window->DeleteUndoFile))
  1168.                             {
  1169.                                 if (!SampleListPasteFromFile(Window->SampleList,
  1170.                                     Window->DeleteUndoFile))
  1171.                                     {
  1172.                                         if (!AlgoSampListPasteFromFile(Window->AlgoSampList,
  1173.                                             Window->DeleteUndoFile))
  1174.                                             {
  1175.                                                 if (!WaveTableListPasteFromFile(Window->WaveTableList,
  1176.                                                     Window->DeleteUndoFile))
  1177.                                                     {
  1178.                                                         if (!AlgoWaveTableListPasteFromFile(Window->AlgoWaveTableList,
  1179.                                                             Window->DeleteUndoFile))
  1180.                                                             {
  1181.                                                                 if (!InstrListPasteFromFile(Window->InstrumentList,
  1182.                                                                     Window->DeleteUndoFile))
  1183.                                                                     {
  1184.                                                                         if (!TrackListPasteFromFile(Window->TrackList,
  1185.                                                                             Window->DeleteUndoFile))
  1186.                                                                             {
  1187.                                                                                 /* couldn't do it, maybe out of memory */
  1188.                                                                                 DidIt = False;
  1189.                                                                             }
  1190.                                                                     }
  1191.                                                             }
  1192.                                                     }
  1193.                                             }
  1194.                                     }
  1195.                             }
  1196.                         if (DidIt)
  1197.                             {
  1198.                                 CloseFile(Window->DeleteUndoFile);
  1199.                                 DeleteFile(Window->DeleteUndoFileLocation);
  1200.                                 DisposeFileSpec(Window->DeleteUndoFileLocation);
  1201.                                 Window->DeleteUndoFileLocation = NIL;
  1202.                                 Window->DeleteUndoFile = NIL;
  1203.                             }
  1204.                     }
  1205.                  else
  1206.                     {
  1207.                         TextEditDoMenuUndo(Window->CommentInfo);
  1208.                     }
  1209.             }
  1210.         else if (MenuItem == mCloseFile)
  1211.             {
  1212.                 CloseDocument(Window);
  1213.             }
  1214.         else if (MenuItem == mOpenObject)
  1215.             {
  1216.                 if (FunctionListIsThereSelection(Window->FunctionList))
  1217.                     {
  1218.                         FunctionListOpenSelection(Window->FunctionList);
  1219.                     }
  1220.                 else if (SampleListIsThereSelection(Window->SampleList))
  1221.                     {
  1222.                         SampleListOpenSelection(Window->SampleList);
  1223.                     }
  1224.                 else if (AlgoSampListIsThereSelection(Window->AlgoSampList))
  1225.                     {
  1226.                         AlgoSampListOpenSelection(Window->AlgoSampList);
  1227.                     }
  1228.                 else if (WaveTableListIsThereSelection(Window->WaveTableList))
  1229.                     {
  1230.                         WaveTableListOpenSelection(Window->WaveTableList);
  1231.                     }
  1232.                 else if (AlgoWaveTableListIsThereSelection(Window->AlgoWaveTableList))
  1233.                     {
  1234.                         AlgoWaveTableListOpenSelection(Window->AlgoWaveTableList);
  1235.                     }
  1236.                 else if (InstrListIsThereSelection(Window->InstrumentList))
  1237.                     {
  1238.                         InstrListOpenSelection(Window->InstrumentList);
  1239.                     }
  1240.                 else if (TrackListIsThereSelection(Window->TrackList))
  1241.                     {
  1242.                         TrackListOpenSelection(Window->TrackList);
  1243.                     }
  1244.                 else
  1245.                     {
  1246.                         EXECUTE(PRERR(AllowResume,
  1247.                             "MainWindowDoMenuCommand(mOpenObject):  no known selection"));
  1248.                     }
  1249.             }
  1250.         else if (MenuItem == mDeleteObject)
  1251.             {
  1252.                 if (FunctionListIsThereSelection(Window->FunctionList))
  1253.                     {
  1254.                         FunctionListDeleteSelection(Window->FunctionList);
  1255.                     }
  1256.                 else if (SampleListIsThereSelection(Window->SampleList))
  1257.                     {
  1258.                         SampleListDeleteSelection(Window->SampleList);
  1259.                     }
  1260.                 else if (AlgoSampListIsThereSelection(Window->AlgoSampList))
  1261.                     {
  1262.                         AlgoSampListDeleteSelection(Window->AlgoSampList);
  1263.                     }
  1264.                 else if (WaveTableListIsThereSelection(Window->WaveTableList))
  1265.                     {
  1266.                         WaveTableListDeleteSelection(Window->WaveTableList);
  1267.                     }
  1268.                 else if (AlgoWaveTableListIsThereSelection(Window->AlgoWaveTableList))
  1269.                     {
  1270.                         AlgoWaveTableListDeleteSelection(Window->AlgoWaveTableList);
  1271.                     }
  1272.                 else if (InstrListIsThereSelection(Window->InstrumentList))
  1273.                     {
  1274.                         InstrListDeleteSelection(Window->InstrumentList);
  1275.                     }
  1276.                 else if (TrackListIsThereSelection(Window->TrackList))
  1277.                     {
  1278.                         TrackListDeleteSelection(Window->TrackList);
  1279.                     }
  1280.                 else
  1281.                     {
  1282.                         EXECUTE(PRERR(AllowResume,
  1283.                             "MainWindowDoMenuCommand(mDeleteObject):  no known selection"));
  1284.                     }
  1285.             }
  1286.         else if (MenuItem == mPasteObject)
  1287.             {
  1288.                 if (!FunctionListPasteObject(Window->FunctionList))
  1289.                     {
  1290.                         if (!SampleListPasteObject(Window->SampleList))
  1291.                             {
  1292.                                 if (!AlgoSampListPasteObject(Window->AlgoSampList))
  1293.                                     {
  1294.                                         if (!WaveTableListPasteObject(Window->WaveTableList))
  1295.                                             {
  1296.                                                 if (!AlgoWaveTableListPasteObject(Window->AlgoWaveTableList))
  1297.                                                     {
  1298.                                                         if (!InstrListPasteObject(Window->InstrumentList))
  1299.                                                             {
  1300.                                                                 if (!TrackListPasteObject(Window->TrackList))
  1301.                                                                     {
  1302.                                                                         /* oh well, it must not be an object */
  1303.                                                                     }
  1304.                                                             }
  1305.                                                     }
  1306.                                             }
  1307.                                     }
  1308.                             }
  1309.                     }
  1310.             }
  1311.         else if (MenuItem == mCopyObject)
  1312.             {
  1313.                 if (FunctionListIsThereSelection(Window->FunctionList))
  1314.                     {
  1315.                         FunctionListCopyObject(Window->FunctionList);
  1316.                     }
  1317.                 else if (SampleListIsThereSelection(Window->SampleList))
  1318.                     {
  1319.                         SampleListCopyObject(Window->SampleList);
  1320.                     }
  1321.                 else if (AlgoSampListIsThereSelection(Window->AlgoSampList))
  1322.                     {
  1323.                         AlgoSampListCopyObject(Window->AlgoSampList);
  1324.                     }
  1325.                 else if (WaveTableListIsThereSelection(Window->WaveTableList))
  1326.                     {
  1327.                         WaveTableListCopyObject(Window->WaveTableList);
  1328.                     }
  1329.                 else if (AlgoWaveTableListIsThereSelection(Window->AlgoWaveTableList))
  1330.                     {
  1331.                         AlgoWaveTableListCopyObject(Window->AlgoWaveTableList);
  1332.                     }
  1333.                 else if (InstrListIsThereSelection(Window->InstrumentList))
  1334.                     {
  1335.                         InstrListCopyObject(Window->InstrumentList);
  1336.                     }
  1337.                 else if (TrackListIsThereSelection(Window->TrackList))
  1338.                     {
  1339.                         TrackListCopyObject(Window->TrackList);
  1340.                     }
  1341.                 else
  1342.                     {
  1343.                         EXECUTE(PRERR(AllowResume,
  1344.                             "MainWindowDoMenuCommand(mCopyObject):  no known selection"));
  1345.                     }
  1346.             }
  1347.         else
  1348.             {
  1349.                 EXECUTE(PRERR(AllowResume,"MainWindowDoMenuCommand:  unknown menu command"));
  1350.             }
  1351.     }
  1352.  
  1353.  
  1354. /* deselect any selection in a scrolling list other than the specified list. */
  1355. /* specified list may be NIL for unconditional deselect */
  1356. void                                MainWindowDeselectAllOtherStringLists(MainWindowRec* Window,
  1357.                                             void* TheDontDeselectStringList)
  1358.     {
  1359.         CheckPtrExistence(Window);
  1360.         if (TheDontDeselectStringList != Window->FunctionList)
  1361.             {
  1362.                 FunctionListDeselect(Window->FunctionList);
  1363.             }
  1364.         if (TheDontDeselectStringList != Window->SampleList)
  1365.             {
  1366.                 SampleListDeselect(Window->SampleList);
  1367.             }
  1368.         if (TheDontDeselectStringList != Window->AlgoSampList)
  1369.             {
  1370.                 AlgoSampListDeselect(Window->AlgoSampList);
  1371.             }
  1372.         if (TheDontDeselectStringList != Window->WaveTableList)
  1373.             {
  1374.                 WaveTableListDeselect(Window->WaveTableList);
  1375.             }
  1376.         if (TheDontDeselectStringList != Window->AlgoWaveTableList)
  1377.             {
  1378.                 AlgoWaveTableListDeselect(Window->AlgoWaveTableList);
  1379.             }
  1380.         if (TheDontDeselectStringList != Window->InstrumentList)
  1381.             {
  1382.                 InstrListDeselect(Window->InstrumentList);
  1383.             }
  1384.         if (TheDontDeselectStringList != Window->TrackList)
  1385.             {
  1386.                 TrackListDeselect(Window->TrackList);
  1387.             }
  1388.     }
  1389.  
  1390.  
  1391. /* create a new calculator window.  the main window keeps track of all calculator */
  1392. /* objects that it has created */
  1393. void                                MainWindowNewCalculator(MainWindowRec* Window)
  1394.     {
  1395.         CalcWindowRec*        Calc;
  1396.  
  1397.         CheckPtrExistence(Window);
  1398.         Calc = NewCalculatorWindow(Window,Window->CodeCenter);
  1399.         if (Calc == NIL)
  1400.             {
  1401.              FailurePoint1:
  1402.                 AlertHalt("There is not enough memory available to "
  1403.                     "open a calculator window.",NIL);
  1404.                 return;
  1405.             }
  1406.         if (!ArrayAppendElement(Window->ListOfCalcWindows,Calc))
  1407.             {
  1408.              FailurePoint2:
  1409.                 DisposeCalculatorWindow(Calc);
  1410.                 goto FailurePoint1;
  1411.             }
  1412.     }
  1413.  
  1414.  
  1415. /* when a calculator window closes, it calls this to make sure the main window */
  1416. /* object knows that it no longer exists */
  1417. void                                MainWindowCalculatorClosingNotify(MainWindowRec* Window,
  1418.                                             CalcWindowRec* Calc)
  1419.     {
  1420.         CheckPtrExistence(Window);
  1421.         ERROR(ArrayFindElement(Window->ListOfCalcWindows,Calc) < 0,PRERR(ForceAbort,
  1422.             "MainWindowCalculatorClosingNotify:  unknown calculator window"));
  1423.         ArrayDeleteElement(Window->ListOfCalcWindows,
  1424.             ArrayFindElement(Window->ListOfCalcWindows,Calc));
  1425.     }
  1426.  
  1427.  
  1428. /* notify the main window that a new disassembly window has been created. */
  1429. MyBoolean                        MainWindowNewDisassemblyNotify(MainWindowRec* Window,
  1430.                                             struct DisaWindowRec* DisassemblyWindow)
  1431.     {
  1432.         CheckPtrExistence(Window);
  1433.         if (!ArrayAppendElement(Window->ListOfDisassemblies,DisassemblyWindow))
  1434.             {
  1435.                 return False;
  1436.             }
  1437.         return True;
  1438.     }
  1439.  
  1440.  
  1441. /* notify the main window that a disassembly window has been destroyed. */
  1442. void                                MainWindowDisassemblyClosingNotify(MainWindowRec* Window,
  1443.                                             struct DisaWindowRec* DisassemblyWindow)
  1444.     {
  1445.         CheckPtrExistence(Window);
  1446.         ERROR(ArrayFindElement(Window->ListOfDisassemblies,DisassemblyWindow) < 0,
  1447.             PRERR(ForceAbort,"MainWindowDisassemblyClosingNotify:  unknown disassembly"));
  1448.         ArrayDeleteElement(Window->ListOfDisassemblies,
  1449.             ArrayFindElement(Window->ListOfDisassemblies,DisassemblyWindow));
  1450.     }
  1451.  
  1452.  
  1453. /* get the number of spaces per tab that editors should use */
  1454. long                                MainWindowGetTabSize(MainWindowRec* Window)
  1455.     {
  1456.         CheckPtrExistence(Window);
  1457.         return Window->TabSize;
  1458.     }
  1459.  
  1460.  
  1461. /* build any function objects that need to be built.  returns True if all of them */
  1462. /* were built without a problem. */
  1463. MyBoolean                        MainWindowMakeUpToDateFunctions(MainWindowRec* Window)
  1464.     {
  1465.         CheckPtrExistence(Window);
  1466.         return FunctionListMakeUpToDate(Window->FunctionList);
  1467.     }
  1468.  
  1469.  
  1470. /* build any algorithmic samples that need to be built.  returns True if all of them */
  1471. /* were built without a problem. */
  1472. MyBoolean                        MainWindowMakeUpToDateAlgoSamps(MainWindowRec* Window)
  1473.     {
  1474.         CheckPtrExistence(Window);
  1475.         return AlgoSampListMakeUpToDate(Window->AlgoSampList);
  1476.     }
  1477.  
  1478.  
  1479. /* build any algorithmic wave tables that need to be built.  returns True if all of */
  1480. /* them were built without a problem. */
  1481. MyBoolean                        MainWindowMakeUpToDateAlgoWaveTables(MainWindowRec* Window)
  1482.     {
  1483.         CheckPtrExistence(Window);
  1484.         return AlgoWaveTableListMakeUpToDate(Window->AlgoWaveTableList);
  1485.     }
  1486.  
  1487.  
  1488. /* build any instrument specifications that need to be built.  returns True if all of */
  1489. /* them were built without a problem. */
  1490. MyBoolean                        MainWindowMakeUpToDateInstrList(MainWindowRec* Window)
  1491.     {
  1492.         CheckPtrExistence(Window);
  1493.         return InstrListMakeUpToDate(Window->InstrumentList);
  1494.     }
  1495.  
  1496.  
  1497. /* build everything.  returns True if everything built correctly */
  1498. MyBoolean                        MainWindowMakeEverythingUpToDate(MainWindowRec* Window)
  1499.     {
  1500.         MyBoolean                    ReturnValue;
  1501.  
  1502.         CheckPtrExistence(Window);
  1503.         ReturnValue = False;
  1504.         SetWatchCursor();
  1505.         if (MainWindowMakeUpToDateFunctions(Window))
  1506.             {
  1507.                 if (MainWindowMakeUpToDateAlgoSamps(Window))
  1508.                     {
  1509.                         if (MainWindowMakeUpToDateAlgoWaveTables(Window))
  1510.                             {
  1511.                                 if (MainWindowMakeUpToDateInstrList(Window))
  1512.                                     {
  1513.                                         ReturnValue = True;
  1514.                                     }
  1515.                             }
  1516.                     }
  1517.             }
  1518.         return ReturnValue;
  1519.     }
  1520.  
  1521.  
  1522. void                                MainWindowEnableGlobalMenus(MainWindowRec* Window)
  1523.     {
  1524.         char*                            StrNumber;
  1525.  
  1526.         CheckPtrExistence(Window);
  1527.         EnableMenuItem(mSaveAs);
  1528.         if (HasDocumentBeenModified(Window) || !Window->EverBeenSaved)
  1529.             {
  1530.                 EnableMenuItem(mSaveFile);
  1531.             }
  1532.         EnableMenuItem(mNewFunction);
  1533.         EnableMenuItem(mNewSample);
  1534.         EnableMenuItem(mNewAlgoSample);
  1535.         EnableMenuItem(mNewWaveTable);
  1536.         EnableMenuItem(mNewAlgoWaveTable);
  1537.         EnableMenuItem(mNewInstrument);
  1538.         EnableMenuItem(mNewTrack);
  1539.         EnableMenuItem(mUnbuildAllFunctions);
  1540.         EnableMenuItem(mBuildEntireProject);
  1541.         EnableMenuItem(mCalculator);
  1542.         EnableMenuItem(mSetTabSize);
  1543.         EnableMenuItem(mPlay);
  1544.  
  1545.         StrNumber = IntegerToString(Window->TabSize);
  1546.         if (StrNumber != NIL)
  1547.             {
  1548.                 char*                            StrKey;
  1549.  
  1550.                 StrKey = StringToBlockCopy("_");
  1551.                 if (StrKey != NIL)
  1552.                     {
  1553.                         char*                            StrValue;
  1554.  
  1555.                         StrValue = StringToBlockCopy("Set Tab Size... (_)");
  1556.                         if (StrValue != NIL)
  1557.                             {
  1558.                                 char*                            StrResult;
  1559.  
  1560.                                 StrResult = ReplaceBlockCopy(StrValue,StrKey,StrNumber);
  1561.                                 if (StrResult != NIL)
  1562.                                     {
  1563.                                         char*                            Temp;
  1564.  
  1565.                                         Temp = BlockToStringCopy(StrResult);
  1566.                                         if (Temp != NIL)
  1567.                                             {
  1568.                                                 ReleasePtr(StrResult);
  1569.                                                 StrResult = Temp;
  1570.                                                 ChangeItemName(mSetTabSize,StrResult);
  1571.                                             }
  1572.                                         ReleasePtr(StrResult);
  1573.                                     }
  1574.                                 ReleasePtr(StrValue);
  1575.                             }
  1576.                         ReleasePtr(StrKey);
  1577.                     }
  1578.                 ReleasePtr(StrNumber);
  1579.             }
  1580.  
  1581.         EnableMenuItem(mImportWAVFormat);
  1582.         EnableMenuItem(mImportRAWFormat);
  1583.         EnableMenuItem(mImportAIFFFormat);
  1584.  
  1585.         WindowMenuEnableItems();
  1586.     }
  1587.  
  1588.  
  1589. /* this checks to see if the menu item is a global menu item.  if it is, the */
  1590. /* associated action is performed and it returns True.  if not, then it returns */
  1591. /* False and the specific editor window must handle the menu item. */
  1592. MyBoolean                        MainWindowDoGlobalMenuItem(MainWindowRec* Window,
  1593.                                             MenuItemType* MenuItem)
  1594.     {
  1595.         CheckPtrExistence(Window);
  1596.         if (MenuItem == mSaveAs)
  1597.             {
  1598.                 SaveDocumentAs(Window);
  1599.             }
  1600.         else if (MenuItem == mSaveFile)
  1601.             {
  1602.                 SaveDocument(Window);
  1603.             }
  1604.         else if (MenuItem == mNewFunction)
  1605.             {
  1606.                 FunctionListNewModule(Window->FunctionList);
  1607.             }
  1608.         else if (MenuItem == mNewSample)
  1609.             {
  1610.                 SampleListNewSample(Window->SampleList);
  1611.             }
  1612.         else if (MenuItem == mNewAlgoSample)
  1613.             {
  1614.                 AlgoSampListNewAlgoSamp(Window->AlgoSampList);
  1615.             }
  1616.         else if (MenuItem == mNewWaveTable)
  1617.             {
  1618.                 WaveTableListNewWaveTable(Window->WaveTableList);
  1619.             }
  1620.         else if (MenuItem == mNewAlgoWaveTable)
  1621.             {
  1622.                 AlgoWaveTableListNewAlgoWaveTable(Window->AlgoWaveTableList);
  1623.             }
  1624.         else if (MenuItem == mNewInstrument)
  1625.             {
  1626.                 InstrListNewInstr(Window->InstrumentList);
  1627.             }
  1628.         else if (MenuItem == mNewTrack)
  1629.             {
  1630.                 TrackListNewTrack(Window->TrackList);
  1631.             }
  1632.         else if (MenuItem == mUnbuildAllFunctions)
  1633.             {
  1634.                 FunctionListUnbuildAll(Window->FunctionList);
  1635.                 AlgoSampListUnbuildAll(Window->AlgoSampList);
  1636.                 AlgoWaveTableListUnbuildAll(Window->AlgoWaveTableList);
  1637.                 InstrListUnbuildAll(Window->InstrumentList);
  1638.             }
  1639.         else if (MenuItem == mBuildEntireProject)
  1640.             {
  1641.                 MainWindowMakeEverythingUpToDate(Window);
  1642.             }
  1643.         else if (MenuItem == mCalculator)
  1644.             {
  1645.                 MainWindowNewCalculator(Window);
  1646.             }
  1647.         else if (MenuItem == mSetTabSize)
  1648.             {
  1649.                 Window->TabSize = DoNumberDialog("Enter new tab size:",Window->TabSize,mCut,
  1650.                     mPaste,mCopy,mUndo,mSelectAll,mClear);
  1651.                 if (Window->TabSize < MINTABCOUNT)
  1652.                     {
  1653.                         Window->TabSize = MINTABCOUNT;
  1654.                     }
  1655.                 if (Window->TabSize > MAXTABCOUNT)
  1656.                     {
  1657.                         Window->TabSize = MAXTABCOUNT;
  1658.                     }
  1659.                 Window->StuffModified = True;
  1660.                 /* we should probably have a dispatch that changes the tab size in */
  1661.                 /* all objects */
  1662.             }
  1663.         else if (MenuItem == mPlay)
  1664.             {
  1665.                 DoPlayPrefsDialog(Window,Window->TrackList);
  1666.             }
  1667.         else if (MenuItem == mImportWAVFormat)
  1668.             {
  1669.                 ImportWAVSample(Window);
  1670.             }
  1671.         else if (MenuItem == mImportRAWFormat)
  1672.             {
  1673.                 ImportRAWSample(Window);
  1674.             }
  1675.         else if (MenuItem == mImportAIFFFormat)
  1676.             {
  1677.                 ImportAIFFSample(Window);
  1678.             }
  1679.         else if (DispatchWindowMenuItem(MenuItem))
  1680.             {
  1681.                 /* no action, but fall through and return True */
  1682.             }
  1683.         else
  1684.             {
  1685.                 return False;
  1686.             }
  1687.         return True;
  1688.     }
  1689.  
  1690.  
  1691. /* get a copy of the left-channel array from a stereo sample.  an error is returned */
  1692. /* indicating the success or failure of this call.  the caller is responsible for */
  1693. /* disposing both the returned array (*DataOut) and the name string */
  1694. SampleErrors                MainWindowGetSampleLeftCopy(void* Window,
  1695.                                             char* NullTerminatedName, largefixedsigned** DataOut)
  1696.     {
  1697.         char*                            NameCopy;
  1698.         SampleErrors            ReturnValue;
  1699.  
  1700.         CheckPtrExistence(Window);
  1701.         NameCopy = StringToBlockCopy(NullTerminatedName);
  1702.         if (NameCopy == NIL)
  1703.             {
  1704.                 return eEvalSampleNotEnoughMemoryToCopy;
  1705.             }
  1706.         ReturnValue = SampleListGetSampleLeftFixed(((MainWindowRec*)Window)->SampleList,
  1707.             NameCopy,DataOut);
  1708.         ReleasePtr(NameCopy);
  1709.         return ReturnValue;
  1710.     }
  1711.  
  1712.  
  1713. /* get a copy of the right-channel array from a stereo sample.  an error is returned */
  1714. /* indicating the success or failure of this call.  the caller is responsible for */
  1715. /* disposing both the returned array (*DataOut) and the name string */
  1716. SampleErrors                MainWindowGetSampleRightCopy(void* Window,
  1717.                                             char* NullTerminatedName, largefixedsigned** DataOut)
  1718.     {
  1719.         char*                            NameCopy;
  1720.         SampleErrors            ReturnValue;
  1721.  
  1722.         CheckPtrExistence(Window);
  1723.         NameCopy = StringToBlockCopy(NullTerminatedName);
  1724.         if (NameCopy == NIL)
  1725.             {
  1726.                 return eEvalSampleNotEnoughMemoryToCopy;
  1727.             }
  1728.         ReturnValue = SampleListGetSampleRightFixed(((MainWindowRec*)Window)->SampleList,
  1729.             NameCopy,DataOut);
  1730.         ReleasePtr(NameCopy);
  1731.         return ReturnValue;
  1732.     }
  1733.  
  1734.  
  1735. /* get a copy of the sample array from a mono sample.  an error is returned */
  1736. /* indicating the success or failure of this call.  the caller is responsible for */
  1737. /* disposing both the returned array (*DataOut) and the name string */
  1738. SampleErrors                MainWindowGetSampleMonoCopy(void* Window,
  1739.                                             char* NullTerminatedName, largefixedsigned** DataOut)
  1740.     {
  1741.         char*                            NameCopy;
  1742.         SampleErrors            ReturnValue;
  1743.  
  1744.         CheckPtrExistence(Window);
  1745.         NameCopy = StringToBlockCopy(NullTerminatedName);
  1746.         if (NameCopy == NIL)
  1747.             {
  1748.                 return eEvalSampleNotEnoughMemoryToCopy;
  1749.             }
  1750.         ReturnValue = SampleListGetSampleMonoFixed(((MainWindowRec*)Window)->SampleList,
  1751.             NameCopy,DataOut);
  1752.         ReleasePtr(NameCopy);
  1753.         return ReturnValue;
  1754.     }
  1755.  
  1756.  
  1757. /* get the number of frames per wave period for the specified wave table.  an error */
  1758. /* code is returned indicating success or failure.  the caller is responsible for */
  1759. /* disposing of the name string. */
  1760. SampleErrors                MainWindowGetWaveTableFrameCount(void* Window,
  1761.                                             char* NullTerminatedName, long* FrameCountOut)
  1762.     {
  1763.         char*                            NameCopy;
  1764.         SampleErrors            ReturnValue;
  1765.  
  1766.         CheckPtrExistence(Window);
  1767.         NameCopy = StringToBlockCopy(NullTerminatedName);
  1768.         if (NameCopy == NIL)
  1769.             {
  1770.                 return eEvalSampleNotEnoughMemoryToCopy;
  1771.             }
  1772.         ReturnValue = WaveTableListGetWaveTableFrameCount(
  1773.             ((MainWindowRec*)Window)->WaveTableList,NameCopy,FrameCountOut);
  1774.         ReleasePtr(NameCopy);
  1775.         return ReturnValue;
  1776.     }
  1777.  
  1778.  
  1779. /* get the number of tables in the specified wave table.  an error */
  1780. /* code is returned indicating success or failure.  the caller is responsible for */
  1781. /* disposing of the name string. */
  1782. SampleErrors                MainWindowGetWaveTableTableCount(void* Window,
  1783.                                             char* NullTerminatedName, long* TableCountOut)
  1784.     {
  1785.         char*                            NameCopy;
  1786.         SampleErrors            ReturnValue;
  1787.  
  1788.         CheckPtrExistence(Window);
  1789.         NameCopy = StringToBlockCopy(NullTerminatedName);
  1790.         if (NameCopy == NIL)
  1791.             {
  1792.                 return eEvalSampleNotEnoughMemoryToCopy;
  1793.             }
  1794.         ReturnValue = WaveTableListGetWaveTableTableCount(
  1795.             ((MainWindowRec*)Window)->WaveTableList,NameCopy,TableCountOut);
  1796.         ReleasePtr(NameCopy);
  1797.         return ReturnValue;
  1798.     }
  1799.  
  1800.  
  1801. /* get a copy of the sample array from a wave table.  an error is returned */
  1802. /* indicating the success or failure of this call.  the caller is responsible for */
  1803. /* disposing both the returned array (*DataOut) and the name string */
  1804. SampleErrors                MainWindowGetWaveTableArray(void* Window,
  1805.                                             char* NullTerminatedName, largefixedsigned** DataOut)
  1806.     {
  1807.         char*                            NameCopy;
  1808.         SampleErrors            ReturnValue;
  1809.  
  1810.         CheckPtrExistence(Window);
  1811.         NameCopy = StringToBlockCopy(NullTerminatedName);
  1812.         if (NameCopy == NIL)
  1813.             {
  1814.                 return eEvalSampleNotEnoughMemoryToCopy;
  1815.             }
  1816.         ReturnValue = WaveTableListGetWaveTableArray(
  1817.             ((MainWindowRec*)Window)->WaveTableList,NameCopy,DataOut);
  1818.         ReleasePtr(NameCopy);
  1819.         return ReturnValue;
  1820.     }
  1821.  
  1822.  
  1823. /* open a new sample editor initialized with the parameters and install the data */
  1824. /* in the array RawData into it.  this array is NOT largefixedsigned, but rather is */
  1825. /* signed char or signed short, depending on the setting of NumBits.  the caller */
  1826. /* is responsible for disposing of RawData. */
  1827. struct SampleObjectRec*    MainWindowCopyRawSampleAndOpen(MainWindowRec* Window,
  1828.                                             char* RawData, NumBitsType NumBits, NumChannelsType NumChannels,
  1829.                                             long Origin, long LoopStart1, long LoopStart2, long LoopStart3,
  1830.                                             long LoopEnd1, long LoopEnd2, long LoopEnd3, long SamplingRate,
  1831.                                             double NaturalFrequency)
  1832.     {
  1833.         CheckPtrExistence(Window);
  1834.         if (RawData != NIL)
  1835.             {
  1836.                 CheckPtrExistence(RawData);
  1837.                 return SampleListCopyRawSampleAndOpen(Window->SampleList,RawData,NumBits,
  1838.                     NumChannels,Origin,LoopStart1,LoopStart2,LoopStart3,LoopEnd1,LoopEnd2,
  1839.                     LoopEnd3,SamplingRate,NaturalFrequency);
  1840.             }
  1841.          else
  1842.             {
  1843.                 return NIL;
  1844.             }
  1845.     }
  1846.  
  1847.  
  1848. /* open a new wave table editor initialized with the parameters and install the data */
  1849. /* in the array RawData into it.  this array is not largefixedsigned, but rather is */
  1850. /* signed char or signed short, depending on the setting of NumBits.  the caller */
  1851. /* is responsible for disposing of RawData. */
  1852. struct WaveTableObjectRec*    MainWindowCopyRawWaveTableAndOpen(MainWindowRec* Window,
  1853.                                             char* RawData, NumBitsType NumBits, long NumTables,
  1854.                                             long FramesPerTable)
  1855.     {
  1856.         CheckPtrExistence(Window);
  1857.         if (RawData != NIL)
  1858.             {
  1859.                 CheckPtrExistence(RawData);
  1860.                 return WaveTableListCopyRawWaveTableAndOpen(Window->WaveTableList,RawData,
  1861.                     NumBits,NumTables,FramesPerTable);
  1862.             }
  1863.          else
  1864.             {
  1865.                 return NIL;
  1866.             }
  1867.     }
  1868.  
  1869.  
  1870. /* get a copy of the name of the current document file.  the name is a heap-allocated */
  1871. /* non-null-terminated block. */
  1872. char*                                GetCopyOfDocumentName(MainWindowRec* Window)
  1873.     {
  1874.         char*                            Filename;
  1875.  
  1876.         if (Window->EverBeenSaved)
  1877.             {
  1878.                 Filename = ExtractFileName(Window->TheFileLocation);
  1879.             }
  1880.          else
  1881.             {
  1882.                 Filename = StringToBlockCopy("Untitled");
  1883.             }
  1884.         if (Filename != NIL)
  1885.             {
  1886.                 SetTag(Filename,"GetCopyOfDocumentName");
  1887.             }
  1888.         return Filename;
  1889.     }
  1890.  
  1891.  
  1892. /* dispatch a name change event.  this tells all editors that the document title */
  1893. /* has changed, and the window titles should be updated accordingly. */
  1894. void                                MainWindowDispatchNameChange(MainWindowRec* Window)
  1895.     {
  1896.         char*                            Filename;
  1897.  
  1898.         CheckPtrExistence(Window);
  1899.         Filename = GetCopyOfDocumentName(Window);
  1900.         if (Filename != NIL)
  1901.             {
  1902.                 char*                            FilenameNullTerminated;
  1903.  
  1904.                 SampleListGlobalNameChange(Window->SampleList,Filename);
  1905.                 FunctionListGlobalNameChange(Window->FunctionList,Filename);
  1906.                 AlgoSampListGlobalNameChange(Window->AlgoSampList,Filename);
  1907.                 WaveTableListGlobalNameChange(Window->WaveTableList,Filename);
  1908.                 AlgoWaveTableListGlobalNameChange(Window->AlgoWaveTableList,Filename);
  1909.                 InstrListGlobalNameChange(Window->InstrumentList,Filename);
  1910.                 TrackListGlobalNameChange(Window->TrackList,Filename);
  1911.                 FilenameNullTerminated = BlockToStringCopy(Filename);
  1912.                 if (FilenameNullTerminated != NIL)
  1913.                     {
  1914.                         SetWindowName(Window->ScreenID,FilenameNullTerminated);
  1915.                         ChangeItemName(Window->MyMenuItem,FilenameNullTerminated);
  1916.                         ReleasePtr(FilenameNullTerminated);
  1917.                     }
  1918.                 ReleasePtr(Filename);
  1919.             }
  1920.     }
  1921.  
  1922.  
  1923. MyBoolean                        MainWindowGetStereo(MainWindowRec* Window)
  1924.     {
  1925.         CheckPtrExistence(Window);
  1926.         return Window->StereoPlayback;
  1927.     }
  1928.  
  1929.  
  1930. MyBoolean                        MainWindowGetSurround(MainWindowRec* Window)
  1931.     {
  1932.         CheckPtrExistence(Window);
  1933.         return Window->SurroundEncoding;
  1934.     }
  1935.  
  1936.  
  1937. long                                MainWindowGetSamplingRate(MainWindowRec* Window)
  1938.     {
  1939.         CheckPtrExistence(Window);
  1940.         return Window->SamplingRate;
  1941.     }
  1942.  
  1943.  
  1944. long                                MainWindowGetEnvelopeRate(MainWindowRec* Window)
  1945.     {
  1946.         CheckPtrExistence(Window);
  1947.         return Window->EnvelopeUpdateRate;
  1948.     }
  1949.  
  1950.  
  1951. double                            MainWindowGetBeatsPerMinute(MainWindowRec* Window)
  1952.     {
  1953.         CheckPtrExistence(Window);
  1954.         return LargeBCD2Double(Window->DefaultBeatsPerMinute);
  1955.     }
  1956.  
  1957.  
  1958. double                            MainWindowGetVolumeScaling(MainWindowRec* Window)
  1959.     {
  1960.         CheckPtrExistence(Window);
  1961.         return LargeBCD2Double(Window->OverallVolumeScalingFactor);
  1962.     }
  1963.  
  1964.  
  1965. OutputNumBitsType        MainWindowGetOutputNumBits(MainWindowRec* Window)
  1966.     {
  1967.         CheckPtrExistence(Window);
  1968.         return Window->OutputNumBits;
  1969.     }
  1970.  
  1971.  
  1972. MyBoolean                        MainWindowGetInterpolationOverTime(MainWindowRec* Window)
  1973.     {
  1974.         CheckPtrExistence(Window);
  1975.         return Window->InterpolateOverTime;
  1976.     }
  1977.  
  1978.  
  1979. MyBoolean                        MainWindowGetInterpolationAcrossWaves(MainWindowRec* Window)
  1980.     {
  1981.         CheckPtrExistence(Window);
  1982.         return Window->InterpolateAcrossWaves;
  1983.     }
  1984.  
  1985.  
  1986. double                            MainWindowGetScanningGap(MainWindowRec* Window)
  1987.     {
  1988.         CheckPtrExistence(Window);
  1989.         return LargeBCD2Double(Window->ScanningGap);
  1990.     }
  1991.  
  1992.  
  1993. double                            MainWindowGetBufferDuration(MainWindowRec* Window)
  1994.     {
  1995.         CheckPtrExistence(Window);
  1996.         return LargeBCD2Double(Window->BufferDuration);
  1997.     }
  1998.  
  1999.  
  2000. MyBoolean                        MainWindowGetClipWarning(MainWindowRec* Window)
  2001.     {
  2002.         CheckPtrExistence(Window);
  2003.         return Window->ClipWarning;
  2004.     }
  2005.  
  2006.  
  2007. char*                                MainWindowGetPostProcessing(MainWindowRec* Window)
  2008.     {
  2009.         char*                            StringTemp;
  2010.  
  2011.         CheckPtrExistence(Window);
  2012.         StringTemp = CopyPtr(Window->SongPostProcessing);
  2013.         if (StringTemp != NIL)
  2014.             {
  2015.                 SetTag(StringTemp,"SongPostProcessing");
  2016.             }
  2017.         return StringTemp;
  2018.     }
  2019.  
  2020.  
  2021. MyBoolean                        MainWindowGetPostProcessingEnable(MainWindowRec* Window)
  2022.     {
  2023.         CheckPtrExistence(Window);
  2024.         return Window->SongPostProcessingEnable;
  2025.     }
  2026.  
  2027.  
  2028. void                                PutMainWindowStereo(MainWindowRec* Window, MyBoolean NewStereoFlag)
  2029.     {
  2030.         CheckPtrExistence(Window);
  2031.         if (Window->StereoPlayback != NewStereoFlag)
  2032.             {
  2033.                 Window->StereoPlayback = NewStereoFlag;
  2034.                 Window->StuffModified = True;
  2035.             }
  2036.     }
  2037.  
  2038.  
  2039. void                                PutMainWindowSurround(MainWindowRec* Window, MyBoolean NewSurround)
  2040.     {
  2041.         CheckPtrExistence(Window);
  2042.         if (Window->SurroundEncoding != NewSurround)
  2043.             {
  2044.                 Window->SurroundEncoding = NewSurround;
  2045.                 Window->StuffModified = True;
  2046.             }
  2047.     }
  2048.  
  2049.  
  2050. void                                PutMainWindowSamplingRate(MainWindowRec* Window,
  2051.                                             long NewSamplingRate)
  2052.     {
  2053.         CheckPtrExistence(Window);
  2054.         if (NewSamplingRate < MINSAMPLINGRATE)
  2055.             {
  2056.                 NewSamplingRate = MINSAMPLINGRATE;
  2057.             }
  2058.         if (NewSamplingRate > MAXSAMPLINGRATE)
  2059.             {
  2060.                 NewSamplingRate = MAXSAMPLINGRATE;
  2061.             }
  2062.         if (Window->SamplingRate != NewSamplingRate)
  2063.             {
  2064.                 Window->SamplingRate = NewSamplingRate;
  2065.                 Window->StuffModified = True;
  2066.             }
  2067.     }
  2068.  
  2069.  
  2070. void                                PutMainWindowEnvelopeRate(MainWindowRec* Window,
  2071.                                             long NewEnvelopeRate)
  2072.     {
  2073.         CheckPtrExistence(Window);
  2074.         if (NewEnvelopeRate < 1)
  2075.             {
  2076.                 NewEnvelopeRate = 1;
  2077.             }
  2078.         if (NewEnvelopeRate > MAXSAMPLINGRATE)
  2079.             {
  2080.                 NewEnvelopeRate = MAXSAMPLINGRATE;
  2081.             }
  2082.         if (Window->EnvelopeUpdateRate != NewEnvelopeRate)
  2083.             {
  2084.                 Window->EnvelopeUpdateRate = NewEnvelopeRate;
  2085.                 Window->StuffModified = True;
  2086.             }
  2087.     }
  2088.  
  2089.  
  2090. void                                PutMainWindowBeatsPerMinute(MainWindowRec* Window,
  2091.                                             double NewBeatsPerMinute)
  2092.     {
  2093.         LargeBCDType            BPM;
  2094.  
  2095.         CheckPtrExistence(Window);
  2096.         BPM = Double2LargeBCD(NewBeatsPerMinute);
  2097.         if (Window->DefaultBeatsPerMinute != BPM)
  2098.             {
  2099.                 Window->DefaultBeatsPerMinute = BPM;
  2100.                 Window->StuffModified = True;
  2101.             }
  2102.     }
  2103.  
  2104.  
  2105. void                                PutMainWindowVolumeScaling(MainWindowRec* Window,
  2106.                                             double NewVolumeScaling)
  2107.     {
  2108.         LargeBCDType            Vol;
  2109.  
  2110.         CheckPtrExistence(Window);
  2111.         Vol = Double2LargeBCD(NewVolumeScaling);
  2112.         if (Window->OverallVolumeScalingFactor != Vol)
  2113.             {
  2114.                 Window->OverallVolumeScalingFactor = Vol;
  2115.                 Window->StuffModified = True;
  2116.             }
  2117.     }
  2118.  
  2119.  
  2120. void                                PutMainWindowOutputNumBits(MainWindowRec* Window,
  2121.                                             OutputNumBitsType NewOutputNumBits)
  2122.     {
  2123.         CheckPtrExistence(Window);
  2124.         ERROR((NewOutputNumBits != eOutput8Bits) && (NewOutputNumBits != eOutput16Bits)
  2125.             && (NewOutputNumBits != eOutput24Bits) && (NewOutputNumBits != eOutput32Bits),
  2126.             PRERR(ForceAbort,"PutMainWindowOutputNumBits:  bad value"));
  2127.         if (Window->OutputNumBits != NewOutputNumBits)
  2128.             {
  2129.                 Window->OutputNumBits = NewOutputNumBits;
  2130.                 Window->StuffModified = True;
  2131.             }
  2132.     }
  2133.  
  2134.  
  2135. void                                PutMainWindowInterpolationOverTime(MainWindowRec* Window,
  2136.                                             MyBoolean NewInterpOverTime)
  2137.     {
  2138.         CheckPtrExistence(Window);
  2139.         if (Window->InterpolateOverTime != NewInterpOverTime)
  2140.             {
  2141.                 Window->InterpolateOverTime = NewInterpOverTime;
  2142.                 Window->StuffModified = True;
  2143.             }
  2144.     }
  2145.  
  2146.  
  2147. void                                PutMainWindowInterpolationAcrossWaves(MainWindowRec* Window,
  2148.                                             MyBoolean NewInterpAcrossWaves)
  2149.     {
  2150.         CheckPtrExistence(Window);
  2151.         if (Window->InterpolateAcrossWaves != NewInterpAcrossWaves)
  2152.             {
  2153.                 Window->InterpolateAcrossWaves = NewInterpAcrossWaves;
  2154.                 Window->StuffModified = True;
  2155.             }
  2156.     }
  2157.  
  2158.  
  2159. void                                PutMainWindowScanningGap(MainWindowRec* Window, double NewScanningGap)
  2160.     {
  2161.         LargeBCDType            Gap;
  2162.  
  2163.         CheckPtrExistence(Window);
  2164.         Gap = Double2LargeBCD(NewScanningGap);
  2165.         if (Gap != Window->ScanningGap)
  2166.             {
  2167.                 Window->ScanningGap = Gap;
  2168.                 Window->StuffModified = True;
  2169.             }
  2170.     }
  2171.  
  2172.  
  2173. void                                PutMainWindowBufferDuration(MainWindowRec* Window,
  2174.                                             double NewBufferDuration)
  2175.     {
  2176.         LargeBCDType            Buffering;
  2177.  
  2178.         CheckPtrExistence(Window);
  2179.         Buffering = Double2LargeBCD(NewBufferDuration);
  2180.         if (Buffering != Window->BufferDuration)
  2181.             {
  2182.                 Window->BufferDuration = Buffering;
  2183.                 Window->StuffModified = True;
  2184.             }
  2185.     }
  2186.  
  2187.  
  2188. void                                PutMainWindowClipWarning(MainWindowRec* Window,
  2189.                                             MyBoolean NewClipWarning)
  2190.     {
  2191.         CheckPtrExistence(Window);
  2192.         if (NewClipWarning != Window->ClipWarning)
  2193.             {
  2194.                 Window->ClipWarning = NewClipWarning;
  2195.                 Window->StuffModified = True;
  2196.             }
  2197.     }
  2198.  
  2199.  
  2200. void                                PutMainWindowPostProcessing(MainWindowRec* Window,
  2201.                                             char* NewPostProcessing)
  2202.     {
  2203.         CheckPtrExistence(Window);
  2204.         CheckPtrExistence(NewPostProcessing);
  2205.         ReleasePtr(Window->SongPostProcessing);
  2206.         Window->SongPostProcessing = NewPostProcessing;
  2207.         Window->StuffModified = True;
  2208.     }
  2209.  
  2210.  
  2211. void                                PutMainWindowPostProcessingEnable(MainWindowRec* Window,
  2212.                                             MyBoolean NewPostProcessingEnable)
  2213.     {
  2214.         CheckPtrExistence(Window);
  2215.         if (Window->SongPostProcessingEnable != NewPostProcessingEnable)
  2216.             {
  2217.                 Window->SongPostProcessingEnable = NewPostProcessingEnable;
  2218.                 Window->StuffModified = True;
  2219.             }
  2220.     }
  2221.  
  2222.  
  2223. /* General Information Subblock Structure: */
  2224. /*   4-byte file format version code */
  2225. /*       "Syn1" - first file format */
  2226. /*   1-byte unsigned tab size code */
  2227. /*       should be in the range of 1..255 */
  2228. /*   4-byte little endian comment text length (positive 2s complement, in bytes) */
  2229. /*   n-byte character data for comment text (line feed = 0x0a) */
  2230. /*   1-byte stereo playback flag */
  2231. /*       0 = mono */
  2232. /*       1 = stereo */
  2233. /*   1-byte surround encoding flag */
  2234. /*       0 = no surround encoding */
  2235. /*       1 = generic surround encoding */
  2236. /*   4-byte little endian output sampling rate */
  2237. /*       should be in the range of 100..65535 */
  2238. /*   4-byte little endian envelope update rate */
  2239. /*       should be in the range of 1..65535 */
  2240. /*   4-byte little endian large integer coded decimal beats per minute */
  2241. /*       large integer coded decimal is decimal * 1000000 with a */
  2242. /*       range of -1999.999999 to 1999.999999 */
  2243. /*   4-byte little endian large integer coded decimal total volume scaling factor */
  2244. /*   1-byte number of bits to output */
  2245. /*       should be 8, 16, 24, or 32 */
  2246. /*   1-byte flag for interpolation over time */
  2247. /*       0 = don't interpolate over time */
  2248. /*       1 = do interpolate over time (when resampling waveforms) */
  2249. /*   1-byte flag for interpolation across waves */
  2250. /*       0 = don't interpolate across waves */
  2251. /*       1 = do interpolate across waves (when wave table synthesis index is */
  2252. /*           not an integer) */
  2253. /*   4-byte little endian large integer coded decimal scanning gap */
  2254. /*   4-byte little endian large integer coded decimal buffer duration (in seconds) */
  2255. /*   1-byte flag for clipping warning */
  2256. /*       0 = don't warn about clipped samples */
  2257. /*       1 = do warn about clipped samples */
  2258. /*   1-byte flag for song post processing enabling */
  2259. /*       0 = don't do song postprocessing */
  2260. /*       1 = do song postprocessing */
  2261. /*   4-byte little endian length of song post processing function */
  2262. /*   n-bytes of post processing function text (line fed = 0x0a) */
  2263.  
  2264.  
  2265. /* read the general information subblock from the specified file. */
  2266. FileLoadingErrors        MainWindowReadData(MainWindowRec* Window,
  2267.                                             struct BufferedInputRec* Input)
  2268.     {
  2269.         char                            FileFormatVersion[4];
  2270.         signed long                BlockLength;
  2271.         char*                            StringTemp;
  2272.         unsigned char            BuffChar;
  2273.         signed long                SignedLong;
  2274.  
  2275.         CheckPtrExistence(Window);
  2276.         CheckPtrExistence(Input);
  2277.  
  2278.         /*   4-byte file format version code */
  2279.         /*       "Syn1" - first file format */
  2280.         if (!ReadBufferedInput(Input,4,FileFormatVersion))
  2281.             {
  2282.                 return eFileLoadDiskError;
  2283.             }
  2284.         if (!MemEqu(FileFormatVersion,"Syn1",4))
  2285.             {
  2286.                 return eFileLoadBadFormat;
  2287.             }
  2288.  
  2289.         /*   1-byte unsigned tab size code */
  2290.         /*       should be in the range of 1..255 */
  2291.         if (!ReadBufferedUnsignedChar(Input,&BuffChar))
  2292.             {
  2293.                 return eFileLoadDiskError;
  2294.             }
  2295.         if (BuffChar < MINTABCOUNT)
  2296.             {
  2297.                 BuffChar = MINTABCOUNT;
  2298.             }
  2299.         if (BuffChar > MAXTABCOUNT)
  2300.             {
  2301.                 BuffChar = MAXTABCOUNT;
  2302.             }
  2303.         Window->TabSize = BuffChar;
  2304.  
  2305.         /*   4-byte little endian comment text length (in bytes) */
  2306.         if (!ReadBufferedSignedLongLittleEndian(Input,&BlockLength))
  2307.             {
  2308.                 return eFileLoadDiskError;
  2309.             }
  2310.         if (BlockLength < 0)
  2311.             {
  2312.                 return eFileLoadBadFormat;
  2313.             }
  2314.         StringTemp = AllocPtrCanFail(BlockLength,"MainWindowReadData:  comment string temp");
  2315.         if (StringTemp == NIL)
  2316.             {
  2317.                 return eFileLoadOutOfMemory;
  2318.             }
  2319.         /*   n-byte character data for comment text (line feed = 0x0a) */
  2320.         if (!ReadBufferedInput(Input,BlockLength,StringTemp))
  2321.             {
  2322.                 ReleasePtr(StringTemp);
  2323.                 return eFileLoadDiskError;
  2324.             }
  2325.         if (!TextEditNewRawData(Window->CommentInfo,StringTemp,"\x0a"))
  2326.             {
  2327.                 ReleasePtr(StringTemp);
  2328.                 return eFileLoadOutOfMemory;
  2329.             }
  2330.         TextEditHasBeenSaved(Window->CommentInfo);
  2331.         ReleasePtr(StringTemp);
  2332.  
  2333.         /*   1-byte stereo playback flag */
  2334.         /*       0 = mono */
  2335.         /*       1 = stereo */
  2336.         if (!ReadBufferedUnsignedChar(Input,&BuffChar))
  2337.             {
  2338.                 return eFileLoadDiskError;
  2339.             }
  2340.         if (BuffChar == 0)
  2341.             {
  2342.                 Window->StereoPlayback = False;
  2343.             }
  2344.         else if (BuffChar == 1)
  2345.             {
  2346.                 Window->StereoPlayback = True;
  2347.             }
  2348.         else
  2349.             {
  2350.                 return eFileLoadBadFormat;
  2351.             }
  2352.  
  2353.         /*   1-byte surround encoding flag */
  2354.         /*       0 = no surround encoding */
  2355.         /*       1 = dolby surround encoding */
  2356.         if (!ReadBufferedUnsignedChar(Input,&BuffChar))
  2357.             {
  2358.                 return eFileLoadDiskError;
  2359.             }
  2360.         if (BuffChar == 0)
  2361.             {
  2362.                 Window->SurroundEncoding = False;
  2363.             }
  2364.         else if (BuffChar == 1)
  2365.             {
  2366.                 Window->SurroundEncoding = True;
  2367.             }
  2368.         else
  2369.             {
  2370.                 return eFileLoadBadFormat;
  2371.             }
  2372.  
  2373.         /*   4-byte little endian output sampling rate */
  2374.         /*       should be in the range of 100..65535 */
  2375.         if (!ReadBufferedSignedLongLittleEndian(Input,&SignedLong))
  2376.             {
  2377.                 return eFileLoadDiskError;
  2378.             }
  2379.         if (SignedLong < MINSAMPLINGRATE)
  2380.             {
  2381.                 SignedLong = MINSAMPLINGRATE;
  2382.             }
  2383.         if (SignedLong > MAXSAMPLINGRATE)
  2384.             {
  2385.                 SignedLong = MAXSAMPLINGRATE;
  2386.             }
  2387.         Window->SamplingRate = SignedLong;
  2388.  
  2389.         /*   4-byte little endian envelope update rate */
  2390.         /*       should be in the range of 1..65535 */
  2391.         if (!ReadBufferedSignedLongLittleEndian(Input,&SignedLong))
  2392.             {
  2393.                 return eFileLoadDiskError;
  2394.             }
  2395.         if (SignedLong < 1)
  2396.             {
  2397.                 SignedLong = 1;
  2398.             }
  2399.         if (SignedLong > MAXSAMPLINGRATE)
  2400.             {
  2401.                 SignedLong = MAXSAMPLINGRATE;
  2402.             }
  2403.         Window->EnvelopeUpdateRate = SignedLong;
  2404.  
  2405.         /*   4-byte little endian large integer coded decimal beats per minute */
  2406.         /*       large integer coded decimal is decimal * 1000000 with a */
  2407.         /*       range of -1999.999999 to 1999.999999 */
  2408.         if (!ReadBufferedSignedLongLittleEndian(Input,&SignedLong))
  2409.             {
  2410.                 return eFileLoadDiskError;
  2411.             }
  2412.         Window->DefaultBeatsPerMinute = SignedLong;
  2413.  
  2414.         /*   4-byte little endian large integer coded total volume scaling factor */
  2415.         if (!ReadBufferedSignedLongLittleEndian(Input,&SignedLong))
  2416.             {
  2417.                 return eFileLoadDiskError;
  2418.             }
  2419.         Window->OverallVolumeScalingFactor = SignedLong;
  2420.  
  2421.         /*   1-byte number of bits to output */
  2422.         /*       should be 8, 16, 24, or 32 */
  2423.         if (!ReadBufferedUnsignedChar(Input,&BuffChar))
  2424.             {
  2425.                 return eFileLoadDiskError;
  2426.             }
  2427.         if (BuffChar == 8)
  2428.             {
  2429.                 Window->OutputNumBits = eOutput8Bits;
  2430.             }
  2431.         else if (BuffChar == 16)
  2432.             {
  2433.                 Window->OutputNumBits = eOutput16Bits;
  2434.             }
  2435.         else if (BuffChar == 24)
  2436.             {
  2437.                 Window->OutputNumBits = eOutput24Bits;
  2438.             }
  2439.         else if (BuffChar == 32)
  2440.             {
  2441.                 Window->OutputNumBits = eOutput32Bits;
  2442.             }
  2443.         else
  2444.             {
  2445.                 return eFileLoadBadFormat;
  2446.             }
  2447.  
  2448.         /*   1-byte flag for interpolation over time */
  2449.         /*       0 = don't interpolate over time */
  2450.         /*       1 = do interpolate over time (when resampling waveforms) */
  2451.         if (!ReadBufferedUnsignedChar(Input,&BuffChar))
  2452.             {
  2453.                 return eFileLoadDiskError;
  2454.             }
  2455.         if (BuffChar == 0)
  2456.             {
  2457.                 Window->InterpolateOverTime = False;
  2458.             }
  2459.         else if (BuffChar == 1)
  2460.             {
  2461.                 Window->InterpolateOverTime = True;
  2462.             }
  2463.         else
  2464.             {
  2465.                 return eFileLoadBadFormat;
  2466.             }
  2467.  
  2468.         /*   1-byte flag for interpolation across waves */
  2469.         /*       0 = don't interpolate across waves */
  2470.         /*       1 = do interpolate across waves (when wave table synthesis index is */
  2471.         /*           not an integer) */
  2472.         if (!ReadBufferedUnsignedChar(Input,&BuffChar))
  2473.             {
  2474.                 return eFileLoadDiskError;
  2475.             }
  2476.         if (BuffChar == 0)
  2477.             {
  2478.                 Window->InterpolateAcrossWaves = False;
  2479.             }
  2480.         else if (BuffChar == 1)
  2481.             {
  2482.                 Window->InterpolateAcrossWaves = True;
  2483.             }
  2484.         else
  2485.             {
  2486.                 return eFileLoadBadFormat;
  2487.             }
  2488.  
  2489.         /*   4-byte little endian large integer coded decimal scanning gap */
  2490.         if (!ReadBufferedSignedLongLittleEndian(Input,&SignedLong))
  2491.             {
  2492.                 return eFileLoadDiskError;
  2493.             }
  2494.         Window->ScanningGap = SignedLong;
  2495.  
  2496.         /*   4-byte little endian large integer coded decimal buffer duration (in seconds) */
  2497.         if (!ReadBufferedSignedLongLittleEndian(Input,&SignedLong))
  2498.             {
  2499.                 return eFileLoadDiskError;
  2500.             }
  2501.         Window->BufferDuration = SignedLong;
  2502.  
  2503.         /*   1-byte flag for clipping warning */
  2504.         /*       0 = don't warn about clipped samples */
  2505.         /*       1 = do warn about clipped samples */
  2506.         if (!ReadBufferedUnsignedChar(Input,&BuffChar))
  2507.             {
  2508.                 return eFileLoadDiskError;
  2509.             }
  2510.         if (BuffChar == 0)
  2511.             {
  2512.                 Window->ClipWarning = False;
  2513.             }
  2514.         else if (BuffChar == 1)
  2515.             {
  2516.                 Window->ClipWarning = True;
  2517.             }
  2518.         else
  2519.             {
  2520.                 return eFileLoadBadFormat;
  2521.             }
  2522.  
  2523.         /*   1-byte flag for song post processing enabling */
  2524.         /*       0 = don't do song postprocessing */
  2525.         /*       1 = do song postprocessing */
  2526.         if (!ReadBufferedUnsignedChar(Input,&BuffChar))
  2527.             {
  2528.                 return eFileLoadDiskError;
  2529.             }
  2530.         if (BuffChar == 0)
  2531.             {
  2532.                 Window->SongPostProcessingEnable = False;
  2533.             }
  2534.         else if (BuffChar == 1)
  2535.             {
  2536.                 Window->SongPostProcessingEnable = True;
  2537.             }
  2538.         else
  2539.             {
  2540.                 return eFileLoadBadFormat;
  2541.             }
  2542.  
  2543.         /*   4-byte little endian length of song post processing function */
  2544.         if (!ReadBufferedSignedLongLittleEndian(Input,&SignedLong))
  2545.             {
  2546.                 return eFileLoadDiskError;
  2547.             }
  2548.         if (SignedLong < 0)
  2549.             {
  2550.                 return eFileLoadBadFormat;
  2551.             }
  2552.  
  2553.         /*   n-bytes of post processing function text (line fed = 0x0a) */
  2554.         StringTemp = AllocPtrCanFail(SignedLong,"SongPostProcessing");
  2555.         if (StringTemp == NIL)
  2556.             {
  2557.                 return eFileLoadOutOfMemory;
  2558.             }
  2559.         if (!ReadBufferedInput(Input,SignedLong,StringTemp))
  2560.             {
  2561.                 ReleasePtr(StringTemp);
  2562.                 return eFileLoadDiskError;
  2563.             }
  2564.         ReleasePtr(Window->SongPostProcessing);
  2565.         Window->SongPostProcessing = StringTemp;
  2566.  
  2567.         return eFileLoadNoError;
  2568.     }
  2569.  
  2570.  
  2571. /* write the general information subblock to the specified file. */
  2572. FileLoadingErrors        MainWindowWriteData(MainWindowRec* Window,
  2573.                                             struct BufferedOutputRec* Output)
  2574.     {
  2575.         char*                            StringTemp;
  2576.  
  2577.         CheckPtrExistence(Window);
  2578.         CheckPtrExistence(Output);
  2579.  
  2580.         /*   4-byte file format version code */
  2581.         /*       "Syn1" - first file format */
  2582.         if (!WriteBufferedOutput(Output,4,"Syn1"))
  2583.             {
  2584.                 return eFileLoadDiskError;
  2585.             }
  2586.  
  2587.         /*   1-byte unsigned tab size code */
  2588.         /*       should be in the range of 1..255 */
  2589.         if (!WriteBufferedUnsignedChar(Output,Window->TabSize))
  2590.             {
  2591.                 return eFileLoadDiskError;
  2592.             }
  2593.  
  2594.         /*   4-byte little endian comment text length (in bytes) */
  2595.         StringTemp = TextEditGetRawData(Window->CommentInfo,"\x0a");
  2596.         if (StringTemp == NIL)
  2597.             {
  2598.                 return eFileLoadOutOfMemory;
  2599.             }
  2600.         if (!WriteBufferedSignedLongLittleEndian(Output,PtrSize(StringTemp)))
  2601.             {
  2602.                 ReleasePtr(StringTemp);
  2603.                 return eFileLoadDiskError;
  2604.             }
  2605.         /*   n-byte character data for comment text (line feed = 0x0a) */
  2606.         if (!WriteBufferedOutput(Output,PtrSize(StringTemp),StringTemp))
  2607.             {
  2608.                 ReleasePtr(StringTemp);
  2609.                 return eFileLoadDiskError;
  2610.             }
  2611.         ReleasePtr(StringTemp);
  2612.  
  2613.         /*   1-byte stereo playback flag */
  2614.         /*       0 = mono */
  2615.         /*       1 = stereo */
  2616.         if (Window->StereoPlayback)
  2617.             {
  2618.                 if (!WriteBufferedUnsignedChar(Output,1))
  2619.                     {
  2620.                         return eFileLoadDiskError;
  2621.                     }
  2622.             }
  2623.          else
  2624.             {
  2625.                 if (!WriteBufferedUnsignedChar(Output,0))
  2626.                     {
  2627.                         return eFileLoadDiskError;
  2628.                     }
  2629.             }
  2630.  
  2631.         /*   1-byte surround encoding flag */
  2632.         /*       0 = no surround encoding */
  2633.         /*       1 = dolby surround encoding */
  2634.         if (Window->SurroundEncoding)
  2635.             {
  2636.                 if (!WriteBufferedUnsignedChar(Output,1))
  2637.                     {
  2638.                         return eFileLoadDiskError;
  2639.                     }
  2640.             }
  2641.          else
  2642.             {
  2643.                 if (!WriteBufferedUnsignedChar(Output,0))
  2644.                     {
  2645.                         return eFileLoadDiskError;
  2646.                     }
  2647.             }
  2648.  
  2649.         /*   4-byte little endian output sampling rate */
  2650.         /*       should be in the range of 100..65535 */
  2651.         if (!WriteBufferedSignedLongLittleEndian(Output,Window->SamplingRate))
  2652.             {
  2653.                 return eFileLoadDiskError;
  2654.             }
  2655.  
  2656.         /*   4-byte little endian envelope update rate */
  2657.         /*       should be in the range of 1..65535 */
  2658.         if (!WriteBufferedSignedLongLittleEndian(Output,Window->EnvelopeUpdateRate))
  2659.             {
  2660.                 return eFileLoadDiskError;
  2661.             }
  2662.  
  2663.         /*   4-byte little endian large integer coded decimal beats per minute */
  2664.         /*       large integer coded decimal is decimal * 1000000 with a */
  2665.         /*       range of -1999.999999 to 1999.999999 */
  2666.         if (!WriteBufferedSignedLongLittleEndian(Output,Window->DefaultBeatsPerMinute))
  2667.             {
  2668.                 return eFileLoadDiskError;
  2669.             }
  2670.  
  2671.         /*   4-byte little endian large integer coded total volume scaling factor */
  2672.         if (!WriteBufferedSignedLongLittleEndian(Output,Window->OverallVolumeScalingFactor))
  2673.             {
  2674.                 return eFileLoadDiskError;
  2675.             }
  2676.  
  2677.         /*   1-byte number of bits to output */
  2678.         /*       should be 8, 16, 24, or 32 */
  2679.         switch (Window->OutputNumBits)
  2680.             {
  2681.                 default:
  2682.                     EXECUTE(PRERR(ForceAbort,"MainWindowWriteData:  bad value in Window->OutputNumBits"));
  2683.                     break;
  2684.                 case eOutput8Bits:
  2685.                     if (!WriteBufferedUnsignedChar(Output,8))
  2686.                         {
  2687.                             return eFileLoadDiskError;
  2688.                         }
  2689.                     break;
  2690.                 case eOutput16Bits:
  2691.                     if (!WriteBufferedUnsignedChar(Output,16))
  2692.                         {
  2693.                             return eFileLoadDiskError;
  2694.                         }
  2695.                     break;
  2696.                 case eOutput24Bits:
  2697.                     if (!WriteBufferedUnsignedChar(Output,24))
  2698.                         {
  2699.                             return eFileLoadDiskError;
  2700.                         }
  2701.                     break;
  2702.                 case eOutput32Bits:
  2703.                     if (!WriteBufferedUnsignedChar(Output,32))
  2704.                         {
  2705.                             return eFileLoadDiskError;
  2706.                         }
  2707.                     break;
  2708.             }
  2709.  
  2710.         /*   1-byte flag for interpolation over time */
  2711.         /*       0 = don't interpolate over time */
  2712.         /*       1 = do interpolate over time (when resampling waveforms) */
  2713.         if (Window->InterpolateOverTime)
  2714.             {
  2715.                 if (!WriteBufferedUnsignedChar(Output,1))
  2716.                     {
  2717.                         return eFileLoadDiskError;
  2718.                     }
  2719.             }
  2720.          else
  2721.             {
  2722.                 if (!WriteBufferedUnsignedChar(Output,0))
  2723.                     {
  2724.                         return eFileLoadDiskError;
  2725.                     }
  2726.             }
  2727.  
  2728.         /*   1-byte flag for interpolation across waves */
  2729.         /*       0 = don't interpolate across waves */
  2730.         /*       1 = do interpolate across waves (when wave table synthesis index is */
  2731.         /*           not an integer) */
  2732.         if (Window->InterpolateAcrossWaves)
  2733.             {
  2734.                 if (!WriteBufferedUnsignedChar(Output,1))
  2735.                     {
  2736.                         return eFileLoadDiskError;
  2737.                     }
  2738.             }
  2739.          else
  2740.             {
  2741.                 if (!WriteBufferedUnsignedChar(Output,0))
  2742.                     {
  2743.                         return eFileLoadDiskError;
  2744.                     }
  2745.             }
  2746.  
  2747.         /*   4-byte little endian large integer coded decimal scanning gap */
  2748.         if (!WriteBufferedSignedLongLittleEndian(Output,Window->ScanningGap))
  2749.             {
  2750.                 return eFileLoadDiskError;
  2751.             }
  2752.  
  2753.         /*   4-byte little endian large integer coded decimal buffer duration (in seconds) */
  2754.         if (!WriteBufferedSignedLongLittleEndian(Output,Window->BufferDuration))
  2755.             {
  2756.                 return eFileLoadDiskError;
  2757.             }
  2758.  
  2759.         /*   1-byte flag for clipping warning */
  2760.         /*       0 = don't warn about clipped samples */
  2761.         /*       1 = do warn about clipped samples */
  2762.         if (Window->ClipWarning)
  2763.             {
  2764.                 if (!WriteBufferedUnsignedChar(Output,1))
  2765.                     {
  2766.                         return eFileLoadDiskError;
  2767.                     }
  2768.             }
  2769.          else
  2770.             {
  2771.                 if (!WriteBufferedUnsignedChar(Output,0))
  2772.                     {
  2773.                         return eFileLoadDiskError;
  2774.                     }
  2775.             }
  2776.  
  2777.         /*   1-byte flag for song post processing enabling */
  2778.         /*       0 = don't do song postprocessing */
  2779.         /*       1 = do song postprocessing */
  2780.         if (Window->SongPostProcessingEnable)
  2781.             {
  2782.                 if (!WriteBufferedUnsignedChar(Output,1))
  2783.                     {
  2784.                         return eFileLoadDiskError;
  2785.                     }
  2786.             }
  2787.          else
  2788.             {
  2789.                 if (!WriteBufferedUnsignedChar(Output,0))
  2790.                     {
  2791.                         return eFileLoadDiskError;
  2792.                     }
  2793.             }
  2794.  
  2795.         /*   4-byte little endian length of song post processing function */
  2796.         StringTemp = MainWindowGetPostProcessing(Window);
  2797.         if (StringTemp == NIL)
  2798.             {
  2799.                 return eFileLoadOutOfMemory;
  2800.             }
  2801.         if (!WriteBufferedSignedLongLittleEndian(Output,PtrSize(StringTemp)))
  2802.             {
  2803.                 ReleasePtr(StringTemp);
  2804.                 return eFileLoadDiskError;
  2805.             }
  2806.  
  2807.         /*   n-bytes of post processing function text (line fed = 0x0a) */
  2808.         if (!WriteBufferedOutput(Output,PtrSize(StringTemp),StringTemp))
  2809.             {
  2810.                 ReleasePtr(StringTemp);
  2811.                 return eFileLoadDiskError;
  2812.             }
  2813.         ReleasePtr(StringTemp);
  2814.  
  2815.         return eFileLoadNoError;
  2816.     }
  2817.  
  2818.  
  2819. /* get the sample list object for the specified document.  the actual thing */
  2820. /* is returned */
  2821. struct SampleListRec*    MainWindowGetSampleList(MainWindowRec* Window)
  2822.     {
  2823.         CheckPtrExistence(Window);
  2824.         return Window->SampleList;
  2825.     }
  2826.  
  2827.  
  2828. /* get the algorithmic sample list object for the specified document.  the actual */
  2829. /* thing is returned. */
  2830. struct AlgoSampListRec*    MainWindowGetAlgoSampList(MainWindowRec* Window)
  2831.     {
  2832.         CheckPtrExistence(Window);
  2833.         return Window->AlgoSampList;
  2834.     }
  2835.  
  2836.  
  2837. /* get the wave table list object for the specified document.  the actual thing */
  2838. /* is returned */
  2839. struct WaveTableListRec*    MainWindowGetWaveTableList(MainWindowRec* Window)
  2840.     {
  2841.         CheckPtrExistence(Window);
  2842.         return Window->WaveTableList;
  2843.     }
  2844.  
  2845.  
  2846. /* get the algorithmic wave table list object for the specified document.  the */
  2847. /* actual thing is returned */
  2848. struct AlgoWaveTableListRec*    MainWindowGetAlgoWaveTableList(MainWindowRec* Window)
  2849.     {
  2850.         CheckPtrExistence(Window);
  2851.         return Window->AlgoWaveTableList;
  2852.     }
  2853.  
  2854.  
  2855. /* get the instrument list object for the specified document.  the actual thing */
  2856. /* is returned */
  2857. struct InstrListRec*    MainWindowGetInstrList(MainWindowRec* Window)
  2858.     {
  2859.         CheckPtrExistence(Window);
  2860.         return Window->InstrumentList;
  2861.     }
  2862.  
  2863.  
  2864. /* this updates the object deletion undo information */
  2865. void                                MainWindowNewDeleteUndoInfo(MainWindowRec* Window,
  2866.                                             struct FileSpec* Location, struct FileType* File)
  2867.     {
  2868.         CheckPtrExistence(Window);
  2869.         CheckPtrExistence(Location);
  2870.         CheckPtrExistence(File);
  2871.         if (Window->DeleteUndoFileLocation != NIL)
  2872.             {
  2873.                 CloseFile(Window->DeleteUndoFile);
  2874.                 DeleteFile(Window->DeleteUndoFileLocation);
  2875.                 DisposeFileSpec(Window->DeleteUndoFileLocation);
  2876.             }
  2877.         Window->DeleteUndoFileLocation = Location;
  2878.         Window->DeleteUndoFile = File;
  2879.     }
  2880.